Skip to content

Commit

Permalink
chore: e2e tests for free text inputs
Browse files Browse the repository at this point in the history
  • Loading branch information
ersimont committed Apr 14, 2018
1 parent 23bce2d commit c69e8ca
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 53 deletions.
12 changes: 12 additions & 0 deletions .idea/runConfigurations/Integration__E2E.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

98 changes: 86 additions & 12 deletions integration/e2e/app.e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,95 @@
import { browser, element, by } from 'protractor';

describe('QuickStart Lib E2E Tests', function () {
import { browser, element, by, ElementFinder, Key } from 'protractor';

describe('ng-app-state E2E Tests', () => {
beforeEach(() => browser.get(''));

afterEach(() => {
browser.manage().logs().get('browser').then((browserLog: any[]) => {
expect(browserLog).toEqual([]);
});
browser
.manage()
.logs()
.get('browser')
.then((browserLog: any[]) => {
const errors = browserLog.filter((entry) => entry.level === 'ERROR');
expect(errors).toEqual([]);
});
});

it('should display lib', () => {
expect(element(by.css('h2')).getText()).toEqual('Hello Angular Library');
});
function getInput(type: string) {
let css = 'input';
if (type) {
css += `[type="${type}"]`;
}
return element(by.css(css));
}

it('should display meaning', () => {
expect(element(by.css('h3')).getText()).toEqual('Meaning is: 42');
});
describe('free text inputs', () => {
function textarea() {
return element(by.css('textarea'));
}

interface ExpectFreeTextOptions {
isColor?: boolean;
}

async function enterAndExpect(
control: string | ElementFinder,
value: string,
options?: ExpectFreeTextOptions,
) {
if (typeof control === 'string') {
control = getInput(control);
}

// https://github.com/angular/protractor/issues/4343#issuecomment-350106755
await control.sendKeys(Key.chord(Key.CONTROL, 'a'));
await control.sendKeys(Key.BACK_SPACE);
await control.clear();
await expectValues('');

await control.sendKeys(value);
await expectValues(value, options);
}

async function expectValues(
value: string,
{ isColor = false }: ExpectFreeTextOptions = {},
) {
const stripped = value.replace(/[\r\n]/g, '');
expect(await getInput('').getAttribute('value')).toEqual(stripped);
expect(await getInput('text').getAttribute('value')).toEqual(stripped);
expect(await getInput('search').getAttribute('value')).toEqual(stripped);
expect(await getInput('tel').getAttribute('value')).toEqual(stripped);
expect(await getInput('password').getAttribute('value')).toEqual(
stripped,
);
expect(await getInput('email').getAttribute('value')).toEqual(stripped);
expect(await getInput('url').getAttribute('value')).toEqual(stripped);
expect(await getInput('color').getAttribute('value')).toEqual(
isColor ? value : '#000000',
);
expect(await textarea().getAttribute('value')).toEqual(value);
}

it('works', async () => {
await expectValues('initial text');
await enterAndExpect('', 'default input');
await enterAndExpect('text', 'text input');
await enterAndExpect('search', 'search input');
await enterAndExpect('tel', 'tel input');
await enterAndExpect('password', 'password input');
await enterAndExpect('email', 'email@input.com');
await enterAndExpect('url', 'http://www.input.com/url');
await enterAndExpect('', '#123456', { isColor: true });

// https://stackoverflow.com/q/36402624/1836506
browser.executeScript(`
input = document.querySelector('input[type="color"]');
input.value = '#654321';
input.dispatchEvent(new Event('input'));
`);
await expectValues('#654321', { isColor: true });

await enterAndExpect(textarea(), 'textarea\nvalue');
});
});
});
38 changes: 10 additions & 28 deletions integration/src/app/app.component.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
<input [nasModel]="store('freeText')">
<br>
<input type="text" [nasModel]="store('freeText')">
<input type="text" [nasModel]="store('freeText')"> Text
<br>
<input type="search" [nasModel]="store('freeText')">
<input type="search" [nasModel]="store('freeText')"> Search
<br>
<input type="tel" [nasModel]="store('freeText')">
<input type="tel" [nasModel]="store('freeText')"> Tel
<br>
<input type="password" [nasModel]="store('freeText')">
<input type="password" [nasModel]="store('freeText')"> Password
<br>
<input type="email" [nasModel]="store('freeText')"> Email
<br>
<input type="url" [nasModel]="store('freeText')"> Url
<br>
<input type="color" [nasModel]="store('freeText')">
<br>
<textarea [nasModel]="store('freeText')"></textarea>

Expand Down Expand Up @@ -68,28 +74,4 @@

<hr>

<input type="email" [nasModel]="store('email')">
<br>
<input [nasModel]="store('email')">

<hr>

<input type="email" [nasModel]="store('email')">
<br>
<input [nasModel]="store('email')">

<hr>

<input type="color" [nasModel]="store('color')">
<br>
<input [nasModel]="store('color')">

<hr>

<input type="url" [nasModel]="store('url')">
<br>
<input [nasModel]="store('url')">

<hr>

<pre>{{ stateString$ | async }}</pre>
3 changes: 0 additions & 3 deletions integration/src/app/integration-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,4 @@ export class IntegrationState {
month = '1980-11';
week = '1980-W45';
time = '10:30';
email = 'username@example.com';
color = '#82f0b4';
url = 'https://github.com/simontonsoftware/ng-app-state';
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Directive, ElementRef, forwardRef } from '@angular/core';
import { Directive, ElementRef, forwardRef, Input } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Directive({
selector: 'input[type=radio][nasModel]',
host: {
'(change)': 'onChange()',
'(change)': 'onChange($event.target.value)',
'(blur)': 'onTouched()',
},
providers: [
Expand All @@ -16,15 +16,13 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
],
})
export class RadioValueAccessorDirective implements ControlValueAccessor {
onChange = () => {};
onChange = (_: any) => {};
onTouched = () => {};

constructor(private elementRef: ElementRef) {}

registerOnChange(fn: any): void {
this.onChange = () => {
fn(this.button.value);
};
this.onChange = fn;
}

registerOnTouched(fn: any): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export class RangeValueAccessorDirective implements ControlValueAccessor {

constructor(private elementRef: ElementRef) {}

writeValue(obj: any): void {
this.range.value = obj;
}

registerOnChange(fn: (_: number | null) => void): void {
this.onChange = (value) => {
fn(isNil(value) ? null : parseFloat(value));
Expand All @@ -37,10 +41,6 @@ export class RangeValueAccessorDirective implements ControlValueAccessor {
this.range.disabled = isDisabled;
}

writeValue(obj: any): void {
this.range.value = obj;
}

private get range() {
return this.elementRef.nativeElement as HTMLInputElement;
}
Expand Down

0 comments on commit c69e8ca

Please sign in to comment.