Skip to content

Commit

Permalink
fix(material-experimental): unit tests getting wrong root element and…
Browse files Browse the repository at this point in the history
… add API for getting property value

Based on the discussion in angular#16697 (comment), these changes fix a couple of things that I ran into while doing the `mat-autocomplete` test harness in angular#16620.

* Fixes querying for elements outside the harness not working, because the wrong root node was set.
* Adds an API to retrieve the value of a property on a DOM node.
  • Loading branch information
crisbeto committed Aug 22, 2019
1 parent fa81811 commit 2c2757f
Show file tree
Hide file tree
Showing 10 changed files with 42 additions and 25 deletions.
4 changes: 4 additions & 0 deletions src/cdk-experimental/testing/protractor/protractor-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,8 @@ export class ProtractorElement implements TestElement {
const {x: left, y: top} = await this.element.getLocation();
return {width, height, left, top};
}

async getPropertyValue(name: string): Promise<any> {
return browser.executeScript(`return arguments[0]['${name}']`, this.element);
}
}
3 changes: 3 additions & 0 deletions src/cdk-experimental/testing/test-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,7 @@ export interface TestElement {

/** Gets the dimensions of the element. */
getDimensions(): Promise<ElementDimensions>;

/** Gets the value of a property of an element. */
getPropertyValue(name: string): Promise<any>;
}
14 changes: 6 additions & 8 deletions src/cdk-experimental/testing/testbed/unit-test-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,7 @@ export class UnitTestElement implements TestElement {

async getAttribute(name: string): Promise<string|null> {
await this._stabilize();
let value = this.element.getAttribute(name);
// If cannot find attribute in the element, also try to find it in property,
// this is useful for input/textarea tags.
if (value === null && name in this.element) {
// We need to cast the element so we can access its properties via string indexing.
return (this.element as unknown as {[key: string]: string|null})[name];
}
return value;
return this.element.getAttribute(name);
}

async hasClass(name: string): Promise<boolean> {
Expand All @@ -139,4 +132,9 @@ export class UnitTestElement implements TestElement {
await this._stabilize();
return this.element.getBoundingClientRect();
}

async getPropertyValue(name: string): Promise<any> {
await this._stabilize();
return (this.element as any)[name];
}
}
14 changes: 10 additions & 4 deletions src/cdk-experimental/testing/tests/protractor.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,10 @@ describe('ProtractorHarnessEnvironment', () => {
it('should be able to clear', async () => {
const input = await harness.input();
await input.sendKeys('Yi');
expect(await input.getAttribute('value')).toBe('Yi');
expect(await input.getPropertyValue('value')).toBe('Yi');

await input.clear();
expect(await input.getAttribute('value')).toBe('');
expect(await input.getPropertyValue('value')).toBe('');
});

it('should be able to click', async () => {
Expand All @@ -204,7 +204,7 @@ describe('ProtractorHarnessEnvironment', () => {
const value = await harness.value();
await input.sendKeys('Yi');

expect(await input.getAttribute('value')).toBe('Yi');
expect(await input.getPropertyValue('value')).toBe('Yi');
expect(await value.text()).toBe('Input: Yi');
});

Expand Down Expand Up @@ -236,7 +236,7 @@ describe('ProtractorHarnessEnvironment', () => {
`;
const memo = await harness.memo();
await memo.sendKeys(memoStr);
expect(await memo.getAttribute('value')).toBe(memoStr);
expect(await memo.getPropertyValue('value')).toBe(memoStr);
});

it('should be able to getCssValue', async () => {
Expand All @@ -254,6 +254,12 @@ describe('ProtractorHarnessEnvironment', () => {
expect(await (await browser.switchTo().activeElement()).getText())
.not.toBe(await button.text());
});

it('should be able to get the value of a property', async () => {
const input = await harness.input();
await input.sendKeys('Hello');
expect(await input.getPropertyValue('value')).toBe('Hello');
});
});

describe('HarnessPredicate', () => {
Expand Down
14 changes: 10 additions & 4 deletions src/cdk-experimental/testing/tests/testbed.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,10 @@ describe('TestbedHarnessEnvironment', () => {
it('should be able to clear', async () => {
const input = await harness.input();
await input.sendKeys('Yi');
expect(await input.getAttribute('value')).toBe('Yi');
expect(await input.getPropertyValue('value')).toBe('Yi');

await input.clear();
expect(await input.getAttribute('value')).toBe('');
expect(await input.getPropertyValue('value')).toBe('');
});

it('should be able to click', async () => {
Expand All @@ -224,7 +224,7 @@ describe('TestbedHarnessEnvironment', () => {
const value = await harness.value();
await input.sendKeys('Yi');

expect(await input.getAttribute('value')).toBe('Yi');
expect(await input.getPropertyValue('value')).toBe('Yi');
expect(await value.text()).toBe('Input: Yi');
});

Expand Down Expand Up @@ -255,7 +255,7 @@ describe('TestbedHarnessEnvironment', () => {
`;
const memo = await harness.memo();
await memo.sendKeys(memoStr);
expect(await memo.getAttribute('value')).toBe(memoStr);
expect(await memo.getPropertyValue('value')).toBe(memoStr);
});

it('should be able to getCssValue', async () => {
Expand All @@ -271,6 +271,12 @@ describe('TestbedHarnessEnvironment', () => {
await button.blur();
expect(activeElementText()).not.toBe(await button.text());
});

it('should be able to get the value of a property', async () => {
const input = await harness.input();
await input.sendKeys('Hello');
expect(await input.getPropertyValue('value')).toBe('Hello');
});
});

describe('HarnessPredicate', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class MatCheckboxHarness extends ComponentHarness {

/** Gets a boolean promise indicating if the checkbox is checked. */
async isChecked(): Promise<boolean> {
const checked = (await this._input()).getAttribute('checked');
const checked = (await this._input()).getPropertyValue('checked');
return coerceBooleanProperty(await checked);
}

Expand All @@ -59,7 +59,7 @@ export class MatCheckboxHarness extends ComponentHarness {

/** Gets a boolean promise indicating if the checkbox is required. */
async isRequired(): Promise<boolean> {
const required = (await this._input()).getAttribute('required');
const required = (await this._input()).getPropertyValue('required');
return coerceBooleanProperty(await required);
}

Expand All @@ -76,7 +76,7 @@ export class MatCheckboxHarness extends ComponentHarness {

/** Gets a promise for the checkbox's value. */
async getValue(): Promise<string|null> {
return (await this._input()).getAttribute('value');
return (await this._input()).getPropertyValue('value');
}

/** Gets a promise for the checkbox's aria-label. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class MatCheckboxHarness extends ComponentHarness {

/** Gets a boolean promise indicating if the checkbox is checked. */
async isChecked(): Promise<boolean> {
const checked = (await this._input()).getAttribute('checked');
const checked = (await this._input()).getPropertyValue('checked');
return coerceBooleanProperty(await checked);
}

Expand Down Expand Up @@ -76,7 +76,7 @@ export class MatCheckboxHarness extends ComponentHarness {

/** Gets a promise for the checkbox's value. */
async getValue(): Promise<string|null> {
return (await this._input()).getAttribute('value');
return (await this._input()).getPropertyValue('value');
}

/** Gets a promise for the checkbox's aria-label. */
Expand Down
4 changes: 2 additions & 2 deletions src/material-experimental/mdc-radio/harness/radio-harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ export class MatRadioButtonHarness extends ComponentHarness {

/** Whether the radio-button is checked. */
async isChecked(): Promise<boolean> {
const checked = (await this._input()).getAttribute('checked');
const checked = (await this._input()).getPropertyValue('checked');
return coerceBooleanProperty(await checked);
}

Expand Down Expand Up @@ -208,7 +208,7 @@ export class MatRadioButtonHarness extends ComponentHarness {
* intentionally have the `[object Object]` as return value.
*/
async getValue(): Promise<string|null> {
return (await this._input()).getAttribute('value');
return (await this._input()).getPropertyValue('value');
}

/** Gets a promise for the radio-button's label text. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class MatSlideToggleHarness extends ComponentHarness {

/** Gets a boolean promise indicating if the slide-toggle is checked. */
async isChecked(): Promise<boolean> {
const checked = (await this._input()).getAttribute('checked');
const checked = (await this._input()).getPropertyValue('checked');
return coerceBooleanProperty(await checked);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class MatSlideToggleHarness extends ComponentHarness {

/** Gets a boolean promise indicating if the slide-toggle is checked. */
async isChecked(): Promise<boolean> {
const checked = (await this._input()).getAttribute('checked');
const checked = (await this._input()).getPropertyValue('checked');
return coerceBooleanProperty(await checked);
}

Expand Down

0 comments on commit 2c2757f

Please sign in to comment.