Skip to content

Commit

Permalink
fix(password): docs & test navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
aesteves60 authored and dpellier committed Jul 29, 2024
1 parent d93708a commit 133a30a
Show file tree
Hide file tree
Showing 12 changed files with 103 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@
}

&__toggle-mask {
color: var(--ods-color-primary-500);
color: var(--ods-color-neutral-600);

&:not(:disabled) {
color: var(--ods-color-primary-500);

&:not(:disabled, &--readonly) {
&:hover {
background-color: var(--ods-color-primary-100);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { AttachInternals, Component, Element, Event, type EventEmitter, type FunctionalComponent, Host, Method, Prop, State, Watch, h } from '@stencil/core';
import { ODS_ICON_NAME } from '../../../../icon/src';
import { ODS_SPINNER_COLOR } from '../../../../spinner/src';
import { ODS_INPUT_TYPE, type OdsInputType } from '../../constants/input-type';
import { handleKeySpace, isPassword, setFormValue } from '../../controller/ods-input';
import { type OdsInputValueChangeEventDetail } from '../../interfaces/events';
Expand Down Expand Up @@ -144,7 +145,7 @@ export class OdsInput {

<div class="ods-input__actions">
{
this.isLoading && <ods-spinner class="ods-input__actions__spinner"></ods-spinner>
this.isLoading && <ods-spinner class="ods-input__actions__spinner" color={ this.isDisabled ? ODS_SPINNER_COLOR.neutral : ODS_SPINNER_COLOR.primary }></ods-spinner>
}
{
hasClearableIcon &&
Expand All @@ -167,7 +168,7 @@ export class OdsInput {
'ods-input__actions__toggle-mask': true,
'ods-input__actions__toggle-mask--readonly': this.isReadonly,
}}
disabled={ this.isDisabled || this.isReadonly }
disabled={ this.isDisabled }
onClick={ this.toggleMask.bind(this) }
onKeyUp={ (event: KeyboardEvent): Promise<void> => handleKeySpace(event, this.isDisabled, this.toggleMask.bind(this)) }>
<ods-icon name={ this.isMasked ? ODS_ICON_NAME.eyeClose : ODS_ICON_NAME.eyeOpen }>
Expand Down
6 changes: 3 additions & 3 deletions packages/ods/src/components/input/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
</ods-input>

<p>Disabled</p>
<ods-input value="Disabled" is-disabled is-clearable>
<ods-input value="Disabled" is-disabled is-clearable is-masked>
</ods-input>

<p>Disabled & Error</p>
Expand Down Expand Up @@ -55,8 +55,8 @@
<ods-input value="Readonly" is-readonly>
</ods-input>

<p>Readonly Clearable</p>
<ods-input value="Readonly" is-readonly is-clearable>
<p>Readonly Clearable Masked</p>
<ods-input value="Readonly" is-readonly is-clearable is-masked>
</ods-input>

<p>Pattern just numbers</p>
Expand Down
49 changes: 20 additions & 29 deletions packages/ods/src/components/input/tests/navigation/ods-input.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ describe('ods-input navigation', () => {
});
}

async function odsInputFocusedElementTagName(): Promise<string | undefined> {
async function odsInputFocusedElementClassName(): Promise<string | undefined> {
return await page.evaluate(() => {
const input = document.querySelector('ods-input');
return input?.shadowRoot?.activeElement?.tagName;
return input?.shadowRoot?.activeElement?.className;
});
}

Expand Down Expand Up @@ -58,23 +58,23 @@ describe('ods-input navigation', () => {
await setup('<ods-input is-clearable></ods-input>');

await page.keyboard.press('Tab');
expect(await odsInputFocusedElementTagName()).toBe('INPUT');
expect(await odsInputFocusedElementClassName()).toContain('ods-input__input');

await page.keyboard.press('Tab');
expect(await odsInputFocusedElementTagName()).not.toBe('BUTTON');
expect(await odsInputFocusedElementClassName()).toBe(undefined);
});

it('Button clearable should be focusable', async() => {
await setup('<ods-input is-clearable value="value"></ods-input>');

await page.keyboard.press('Tab');
expect(await odsInputFocusedElementTagName()).toBe('INPUT');
expect(await odsInputFocusedElementClassName()).toContain('ods-input__input');

await page.keyboard.press('Tab');
expect(await odsInputFocusedElementTagName()).toBe('BUTTON');
expect(await odsInputFocusedElementClassName()).toContain('ods-input__actions__clearable');

await page.keyboard.press('Tab');
expect(await odsInputFocusedElementTagName()).not.toBe('BUTTON');
expect(await odsInputFocusedElementClassName()).toBe(undefined);
});

it('should clear input when Enter on clearable button', async() => {
Expand All @@ -89,7 +89,7 @@ describe('ods-input navigation', () => {

expect(await el.getProperty('value')).toBeNull();
expect(odsClearSpy).toHaveReceivedEventTimes(1);
expect(await odsInputFocusedElementTagName()).toBe('INPUT');
expect(await odsInputFocusedElementClassName()).toContain('ods-input__input');
});

it('should clear input when Space on clearable button', async() => {
Expand All @@ -104,7 +104,7 @@ describe('ods-input navigation', () => {

expect(await el.getProperty('value')).toBeNull();
expect(odsClearSpy).toHaveReceivedEventTimes(1);
expect(await odsInputFocusedElementTagName()).toBe('INPUT');
expect(await odsInputFocusedElementClassName()).toContain('ods-input__input');
});

it('should clear input when click on clearable button', async() => {
Expand All @@ -117,7 +117,7 @@ describe('ods-input navigation', () => {

expect(await el.getProperty('value')).toBeNull();
expect(odsClearSpy).toHaveReceivedEventTimes(1);
expect(await odsInputFocusedElementTagName()).toBe('INPUT');
expect(await odsInputFocusedElementClassName()).toContain('ods-input__input');
});

it('should do nothing because of disabled', async() => {
Expand Down Expand Up @@ -166,13 +166,13 @@ describe('ods-input navigation', () => {
await setup('<ods-input is-masked></ods-input>');

await page.keyboard.press('Tab');
expect(await odsInputFocusedElementTagName()).toBe('INPUT');
expect(await odsInputFocusedElementClassName()).toContain('ods-input__input');

await page.keyboard.press('Tab');
expect(await odsInputFocusedElementTagName()).toBe('BUTTON');
expect(await odsInputFocusedElementClassName()).toContain('ods-input__actions__toggle-mask');

await page.keyboard.press('Tab');
expect(await odsInputFocusedElementTagName()).not.toBe('BUTTON');
expect(await odsInputFocusedElementClassName()).toBe(undefined);
});

it('should masked input when Enter on masked button', async() => {
Expand Down Expand Up @@ -236,37 +236,28 @@ describe('ods-input navigation', () => {
expect(odsToggleMaskSpy).not.toHaveReceivedEvent();
});

it('should do nothing because of readonly', async() => {
it('should toggle masked when click on masked button with readonly', async() => {
await setup('<ods-input is-readonly is-masked value="value"></ods-input>');
const odsToggleMaskSpy = await page.spyOnEvent('odsToggleMask');
expect(await input.getProperty('type')).toBe('password');

await page.keyboard.press('Tab');
await page.keyboard.press('Tab');
await page.keyboard.press('Space');
await page.waitForChanges();
expect(await input.getProperty('type')).toBe('password');

await page.keyboard.press('Enter');
await page.waitForChanges();
expect(await input.getProperty('type')).toBe('password');

await buttonToggleMask.click();
await page.waitForChanges();
expect(await input.getProperty('type')).toBe('password');
expect(odsToggleMaskSpy).not.toHaveReceivedEvent();

expect(await input.getProperty('type')).toBe('text');
expect(odsToggleMaskSpy).toHaveReceivedEventTimes(1);
});
});

it('should have 2 button focusable with masked & clearable', async() => {
await setup('<ods-input is-masked is-clearable value="value"></ods-input>');
await page.keyboard.press('Tab');
expect(await odsInputFocusedElementTagName()).toBe('INPUT');
expect(await odsInputFocusedElementClassName()).toContain('ods-input__input');

await page.keyboard.press('Tab');
expect(await odsInputFocusedElementTagName()).toBe('BUTTON');
expect(await odsInputFocusedElementClassName()).toContain('ods-input__actions__clearable');

await page.keyboard.press('Tab');
expect(await odsInputFocusedElementTagName()).toBe('BUTTON');
expect(await odsInputFocusedElementClassName()).toContain('ods-input__actions__toggle-mask');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export class OdsPassword {
isRequired={ this.isRequired }
name={ this.name }
onOdsToggleMask={ () => this.isMasked = !this.isMasked }
onOdsChange={ this.onOdsChange.bind(this) }
onOdsChange={ (event: OdsInputValueChangeEvent) => this.onOdsChange(event) }
exportparts="input"
pattern={ this.pattern }
placeholder={ this.placeholder }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,35 @@ describe('ods-password behaviour', () => {
expect(odsChangeSpy).not.toHaveReceivedEvent();
});
});

describe('Form', () => {
it('should get form data with button type submit', async() => {
await setup(`<form method="get">
<ods-password name="odsPassword" value="On Vous Heberge ?"></ods-password>
<button type="reset">Reset</button>
<button type="submit">Submit</button>
</form>`);
const submitButton = await page.find('button[type="submit"]');
await submitButton.click();
await page.waitForNetworkIdle();
const url = new URL(page.url());
expect(url.searchParams.get('odsPassword')).toBe('On Vous Heberge ?');
});

it('should reset form with button type reset', async() => {
await setup(`<form method="get">
<ods-password name="odsPassword" value="On Vous Heberge ?"></ods-password>
<button type="reset">Reset</button>
<button type="submit">Submit</button>
</form>`);
const resetButton = await page.find('button[type="reset"]');
await resetButton.click();

const submitButton = await page.find('button[type="submit"]');
await submitButton.click();
await page.waitForNetworkIdle();
const url = new URL(page.url());
expect(url.searchParams.get('odsPassword')).toBe('');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ describe('ods-password navigation', () => {
}, buttonSelector);
}

async function odsPasswordFocusedElementTagName(): Promise<string | undefined> {
async function odsPasswordFocusedElementClassName(): Promise<string | undefined> {
return await page.evaluate(() => {
const input = document.querySelector('ods-password')?.shadowRoot?.querySelector('ods-input');
return input?.shadowRoot?.activeElement?.tagName;
return input?.shadowRoot?.activeElement?.className;
});
}

Expand Down Expand Up @@ -60,32 +60,32 @@ describe('ods-password navigation', () => {
await setup('<ods-password is-clearable></ods-password>');

await page.keyboard.press('Tab');
expect(await odsPasswordFocusedElementTagName()).toBe('INPUT');
expect(await odsPasswordFocusedElementClassName()).toContain('ods-input__input');

// Masked button
await page.keyboard.press('Tab');
expect(await odsPasswordFocusedElementTagName()).toBe('BUTTON');
expect(await odsPasswordFocusedElementClassName()).toContain('ods-input__actions__toggle-mask');

await page.keyboard.press('Tab');
expect(await odsPasswordFocusedElementTagName()).not.toBe('BUTTON');
expect(await odsPasswordFocusedElementClassName()).toBe(undefined);
});

it('Button clearable should be focusable', async() => {
await setup('<ods-password is-clearable value="value"></ods-password>');

await page.keyboard.press('Tab');
expect(await odsPasswordFocusedElementTagName()).toBe('INPUT');
expect(await odsPasswordFocusedElementClassName()).toContain('ods-input__input');

// Cleared button
await page.keyboard.press('Tab');
expect(await odsPasswordFocusedElementTagName()).toBe('BUTTON');
expect(await odsPasswordFocusedElementClassName()).toContain('ods-input__actions__clearable');

// Masked button
await page.keyboard.press('Tab');
expect(await odsPasswordFocusedElementTagName()).toBe('BUTTON');
expect(await odsPasswordFocusedElementClassName()).toContain('ods-input__actions__toggle-mask');

await page.keyboard.press('Tab');
expect(await odsPasswordFocusedElementTagName()).not.toBe('BUTTON');
expect(await odsPasswordFocusedElementClassName()).toBe(undefined);
});

it('should clear password when Enter on clearable button', async() => {
Expand All @@ -100,7 +100,7 @@ describe('ods-password navigation', () => {

expect(await el.getProperty('value')).toBeNull();
expect(odsClearSpy).toHaveReceivedEventTimes(1);
expect(await odsPasswordFocusedElementTagName()).toBe('INPUT');
expect(await odsPasswordFocusedElementClassName()).toContain('ods-input__input');
});

it('should clear password when Space on clearable button', async() => {
Expand All @@ -115,7 +115,7 @@ describe('ods-password navigation', () => {

expect(await el.getProperty('value')).toBeNull();
expect(odsClearSpy).toHaveReceivedEventTimes(1);
expect(await odsPasswordFocusedElementTagName()).toBe('INPUT');
expect(await odsPasswordFocusedElementClassName()).toContain('ods-input__input');
});

it('should clear password when click on clearable button', async() => {
Expand All @@ -128,7 +128,7 @@ describe('ods-password navigation', () => {

expect(await el.getProperty('value')).toBeNull();
expect(odsClearSpy).toHaveReceivedEventTimes(1);
expect(await odsPasswordFocusedElementTagName()).toBe('INPUT');
expect(await odsPasswordFocusedElementClassName()).toContain('ods-input__input');
});

it('should do nothing because of disabled', async() => {
Expand Down Expand Up @@ -177,14 +177,14 @@ describe('ods-password navigation', () => {
await setup('<ods-password></ods-password>');

await page.keyboard.press('Tab');
expect(await odsPasswordFocusedElementTagName()).toBe('INPUT');
expect(await odsPasswordFocusedElementClassName()).toContain('ods-input__input');

// Masked Button
await page.keyboard.press('Tab');
expect(await odsPasswordFocusedElementTagName()).toBe('BUTTON');
expect(await odsPasswordFocusedElementClassName()).toContain('ods-input__actions__toggle-mask');

await page.keyboard.press('Tab');
expect(await odsPasswordFocusedElementTagName()).not.toBe('BUTTON');
expect(await odsPasswordFocusedElementClassName()).toBe(undefined);
});

it('should toggle masked when click on masked button', async() => {
Expand Down Expand Up @@ -214,21 +214,14 @@ describe('ods-password navigation', () => {
expect(odsToggleMaskSpy).not.toHaveReceivedEvent();
});

it('should do nothing because of readonly', async() => {
await setup('<ods-password is-readonly value="value"></ods-password>');
it('should toggle masked when click on masked button with readonly', async() => {
await setup('<ods-password value="value"></ods-password>');
const odsToggleMaskSpy = await page.spyOnEvent('odsToggleMask');

await page.keyboard.press('Tab');
await page.keyboard.press('Tab');
await page.keyboard.press('Space');
await page.waitForChanges();

await page.keyboard.press('Enter');
await page.waitForChanges();

await clickOnInputButton('.ods-input__actions__toggle-mask');
await page.waitForChanges();
expect(odsToggleMaskSpy).not.toHaveReceivedEvent();

expect(odsToggleMaskSpy).toHaveReceivedEventTimes(1);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -25,35 +25,4 @@ describe('ods-password rendering', () => {
expect(partStyle.getPropertyValue('width')).toBe('100px');
});
});

describe('Form', () => {
it('should get form data with button type submit', async() => {
await setup(`<form method="get">
<ods-password name="odsPassword" value="On Vous Heberge ?"></ods-password>
<button type="reset">Reset</button>
<button type="submit">Submit</button>
</form>`);
const submitButton = await page.find('button[type="submit"]');
await submitButton.click();
await page.waitForNetworkIdle();
const url = new URL(page.url());
expect(url.searchParams.get('odsPassword')).toBe('On Vous Heberge ?');
});

it('should reset form with button type reset', async() => {
await setup(`<form method="get">
<ods-password name="odsPassword" value="On Vous Heberge ?"></ods-password>
<button type="reset">Reset</button>
<button type="submit">Submit</button>
</form>`);
const resetButton = await page.find('button[type="reset"]');
await resetButton.click();

const submitButton = await page.find('button[type="submit"]');
await submitButton.click();
await page.waitForNetworkIdle();
const url = new URL(page.url());
expect(url.searchParams.get('odsPassword')).toBe('');
});
});
});
Loading

0 comments on commit 133a30a

Please sign in to comment.