Skip to content

Commit

Permalink
refactor(elements/ino-currency-input): migrate stencil e2e tests to p…
Browse files Browse the repository at this point in the history
…laywright (#1329)

* migrate ino-currency-input tests

* refactor: use fill instead of setting the value

* refactor: move type function to utility

* refactor: formatting

---------

Co-authored-by: Jan-Niklas Voß <[email protected]>
  • Loading branch information
BenPag and janivo authored Mar 25, 2024
1 parent b410632 commit 1dfdd1c
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 174 deletions.
12 changes: 4 additions & 8 deletions packages/elements/setupSpecTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@
observe() {}
};

jest.mock('@material/textfield', () => ({
...jest.requireActual('@material/textfield'),
MDCTextField: class {
public focus = jest.fn();
public destroy = jest.fn();
public value = '';
},
}));
HTMLInputElement.prototype.checkValidity = jest.fn();
HTMLInputElement.prototype.setSelectionRange = jest.fn();

jest.mock('@material/textfield');

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { newSpecPage, SpecPage } from '@stencil/core/testing';
import { fillInput, listenForEvent } from '../../util/test-utils';
import { CurrencyInput } from './ino-currency-input';
import { Input } from '../ino-input/ino-input';
import { Label } from '../ino-label/ino-label';

const testValue = 0;
const CONTENT = `
<ino-currency-input value="${testValue}">
<ino-input type="text"></ino-input>
</ino-currency-input>
`;

const NATIVE_INPUT_SELECTOR = 'ino-input > .mdc-text-field > input';

describe('InoCurrencyInput - Events', () => {
let page: SpecPage;
let inoCurrencyInput: HTMLInoCurrencyInputElement;
let nativeInput: HTMLInputElement;

beforeEach(async () => {
page = await newSpecPage({
components: [CurrencyInput, Input, Label],
html: CONTENT,
});
inoCurrencyInput = page.body.querySelector('ino-currency-input');
nativeInput = inoCurrencyInput.querySelector(NATIVE_INPUT_SELECTOR);
});

it.only('should fire valueChange on user input', async () => {
const { eventSpy, assertEventDetails } = listenForEvent(
page,
'valueChange',
);
expect(eventSpy).not.toHaveBeenCalled();

await fillInput(page, nativeInput, '5000,99');

assertEventDetails(5);
const lastEventIndex = eventSpy.mock.calls.length - 1;
assertEventDetails(5000.99, lastEventIndex);
});

it('should not fire on non numeric values', async () => {
const { eventSpy, assertEventDetails } = listenForEvent(
page,
'valueChange',
);
expect(eventSpy).not.toHaveBeenCalled();

await fillInput(page, nativeInput, '1a');
assertEventDetails(1);
});

it('should not fire on more than two decimals', async () => {
const { eventSpy, assertEventDetails } = listenForEvent(
page,
'valueChange',
);
expect(eventSpy).not.toHaveBeenCalled();

await fillInput(page, nativeInput, '11,119');

const lastEventIndex = eventSpy.mock.calls.length - 1;
assertEventDetails(11.11, lastEventIndex);
});

it('should accept zero values (controlled)', async () => {
const expected = Intl.NumberFormat('de-DE', {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}).format(testValue);

expect(nativeInput.value).toBe(expected);
});
});
8 changes: 5 additions & 3 deletions packages/elements/src/components/ino-input/ino-input.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { MDCTextField } from '@material/textfield';
import { MDCTextFieldHelperText } from '@material/textfield/helper-text';
import { MDCTextFieldIcon } from '@material/textfield/icon';
import {
MDCTextField,
MDCTextFieldHelperText,
MDCTextFieldIcon,
} from '@material/textfield';
import {
Component,
ComponentInterface,
Expand Down
36 changes: 18 additions & 18 deletions packages/elements/src/util/test-utils.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
import { E2EPage, SpecPage } from '@stencil/core/testing';

export async function getFocusedElementOfPage(page: E2EPage) {
return page.$eval(':focus', (el) => el);
}
import { SpecPage } from '@stencil/core/testing';

export function listenForEvent(page: SpecPage, eventName: string) {
const eventSpy = jest.fn();

page.body.addEventListener(eventName, eventSpy);

function assertEventDetails(detail: any) {
return expect(eventSpy.mock.calls[0][0]).toHaveProperty('detail', detail);
function assertEventDetails(detail: any, eventIndex = 0) {
return expect(eventSpy.mock.calls[eventIndex][0]).toHaveProperty(
'detail',
detail,
);
}

return { eventSpy, assertEventDetails };
}

export const pxToNumber = (s: string): number =>
Number(s.substring(0, s.length - 2));

export const setPropertyOfEl = <Component extends HTMLElement>(
page: E2EPage,
selector: string,
props: Partial<Component>,
) => {
return page.$eval(selector, (el: Component) => {
Object.assign(el, props);
export async function fillInput(
page: SpecPage,
input: HTMLInputElement,
stringToType: string,
) {
const arr = [...stringToType];
input.value = '';
arr.forEach((char) => {
input.value += char;
input.dispatchEvent(new Event('input'));
});
};
await page.waitForChanges();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { expect, Locator, test } from '@playwright/test';
import { goToStory, setAttribute, setProperty } from '../test-utils';

test.describe('ino-currency-input', () => {
let inoCurrencyInput: Locator;
let input: Locator;
let inoInput: Locator;
let hiddenInput: Locator;

test.beforeEach(async ({ page }) => {
await goToStory(page, ['Input', 'ino-currency-input', 'default']);
inoCurrencyInput = page.locator('ino-currency-input');
hiddenInput = inoCurrencyInput.locator('input[type=hidden]');
inoInput = inoCurrencyInput.locator('ino-input');
input = inoInput.getByRole('textbox');
await setAttribute(inoCurrencyInput, 'value', '');
});

test('should set value attribute', async () => {
await input.fill('500,00');
await input.blur();
await expect(input).toHaveValue('500,00');
await expect(hiddenInput).toHaveValue('500');
});

test('should format thousands on blur', async () => {
await input.fill('15000,99');
await input.blur();
await expect(input).toHaveValue('15.000,99');
});

test('should render with different locale', async () => {
await setAttribute(inoCurrencyInput, 'currency-locale', 'en-US');
await input.fill('15000.99');
await input.blur();
await expect(input).toHaveValue('15,000.99');
});

test('should allow negative inputs', async () => {
await input.fill('-1500,00');
await expect(input).toHaveValue('-1500,00');
await expect(hiddenInput).toHaveValue('-1500');
});

test('should prevent negative inputs on min=0', async () => {
await setProperty(inoInput, 'min', '0');
await input.fill('-1500,00');
await expect(hiddenInput).toHaveValue('1500');
});
});

0 comments on commit 1dfdd1c

Please sign in to comment.