mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00

This patch moves fixtures.js to base.fixtures.ts that sits next to tests. All tests get an extra import to get the base fixtures (both types and implementations).
372 lines
12 KiB
JavaScript
372 lines
12 KiB
JavaScript
/**
|
|
* Copyright 2018 Google Inc. All rights reserved.
|
|
* Modifications copyright (c) Microsoft Corporation.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
require('./base.fixture');
|
|
|
|
const {FFOX, CHROMIUM, WEBKIT} = testOptions;
|
|
|
|
it('should work', async function({page}) {
|
|
await page.setContent(`
|
|
<head>
|
|
<title>Accessibility Test</title>
|
|
</head>
|
|
<body>
|
|
<h1>Inputs</h1>
|
|
<input placeholder="Empty input" autofocus />
|
|
<input placeholder="readonly input" readonly />
|
|
<input placeholder="disabled input" disabled />
|
|
<input aria-label="Input with whitespace" value=" " />
|
|
<input value="value only" />
|
|
<input aria-placeholder="placeholder" value="and a value" />
|
|
<div aria-hidden="true" id="desc">This is a description!</div>
|
|
<input aria-placeholder="placeholder" value="and a value" aria-describedby="desc" />
|
|
</body>`);
|
|
// autofocus happens after a delay in chrome these days
|
|
await page.waitForFunction(() => document.activeElement.hasAttribute('autofocus'));
|
|
|
|
const golden = FFOX ? {
|
|
role: 'document',
|
|
name: 'Accessibility Test',
|
|
children: [
|
|
{role: 'heading', name: 'Inputs', level: 1},
|
|
{role: 'textbox', name: 'Empty input', focused: true},
|
|
{role: 'textbox', name: 'readonly input', readonly: true},
|
|
{role: 'textbox', name: 'disabled input', disabled: true},
|
|
{role: 'textbox', name: 'Input with whitespace', value: ' '},
|
|
{role: 'textbox', name: '', value: 'value only'},
|
|
{role: 'textbox', name: '', value: 'and a value'}, // firefox doesn't use aria-placeholder for the name
|
|
{role: 'textbox', name: '', value: 'and a value', description: 'This is a description!'}, // and here
|
|
]
|
|
} : CHROMIUM ? {
|
|
role: 'WebArea',
|
|
name: 'Accessibility Test',
|
|
children: [
|
|
{role: 'heading', name: 'Inputs', level: 1},
|
|
{role: 'textbox', name: 'Empty input', focused: true},
|
|
{role: 'textbox', name: 'readonly input', readonly: true},
|
|
{role: 'textbox', name: 'disabled input', disabled: true},
|
|
{role: 'textbox', name: 'Input with whitespace', value: ' '},
|
|
{role: 'textbox', name: '', value: 'value only'},
|
|
{role: 'textbox', name: 'placeholder', value: 'and a value'},
|
|
{role: 'textbox', name: 'placeholder', value: 'and a value', description: 'This is a description!'},
|
|
]
|
|
} : {
|
|
role: 'WebArea',
|
|
name: 'Accessibility Test',
|
|
children: [
|
|
{role: 'heading', name: 'Inputs', level: 1},
|
|
{role: 'textbox', name: 'Empty input', focused: true},
|
|
{role: 'textbox', name: 'readonly input', readonly: true},
|
|
{role: 'textbox', name: 'disabled input', disabled: true},
|
|
{role: 'textbox', name: 'Input with whitespace', value: ' ' },
|
|
{role: 'textbox', name: '', value: 'value only' },
|
|
{role: 'textbox', name: 'placeholder', value: 'and a value'},
|
|
{role: 'textbox', name: 'This is a description!',value: 'and a value'}, // webkit uses the description over placeholder for the name
|
|
]
|
|
};
|
|
expect(await page.accessibility.snapshot()).toEqual(golden);
|
|
});
|
|
|
|
it('should work with regular text', async({page}) => {
|
|
await page.setContent(`<div>Hello World</div>`);
|
|
const snapshot = await page.accessibility.snapshot();
|
|
expect(snapshot.children[0]).toEqual({
|
|
role: FFOX ? 'text leaf' : 'text',
|
|
name: 'Hello World',
|
|
});
|
|
});
|
|
|
|
it('roledescription', async({page}) => {
|
|
await page.setContent('<div tabIndex=-1 aria-roledescription="foo">Hi</div>');
|
|
const snapshot = await page.accessibility.snapshot();
|
|
expect(snapshot.children[0].roledescription).toEqual('foo');
|
|
});
|
|
|
|
it('orientation', async({page}) => {
|
|
await page.setContent('<a href="" role="slider" aria-orientation="vertical">11</a>');
|
|
const snapshot = await page.accessibility.snapshot();
|
|
expect(snapshot.children[0].orientation).toEqual('vertical');
|
|
});
|
|
|
|
it('autocomplete', async({page}) => {
|
|
await page.setContent('<div role="textbox" aria-autocomplete="list">hi</div>');
|
|
const snapshot = await page.accessibility.snapshot();
|
|
expect(snapshot.children[0].autocomplete).toEqual('list');
|
|
});
|
|
|
|
it('multiselectable', async({page}) => {
|
|
await page.setContent('<div role="grid" tabIndex=-1 aria-multiselectable=true>hey</div>');
|
|
const snapshot = await page.accessibility.snapshot();
|
|
expect(snapshot.children[0].multiselectable).toEqual(true);
|
|
});
|
|
|
|
it('keyshortcuts', async({page}) => {
|
|
await page.setContent('<div role="grid" tabIndex=-1 aria-keyshortcuts="foo">hey</div>');
|
|
const snapshot = await page.accessibility.snapshot();
|
|
expect(snapshot.children[0].keyshortcuts).toEqual('foo');
|
|
});
|
|
|
|
it('should not report text nodes inside controls', async function({page}) {
|
|
await page.setContent(`
|
|
<div role="tablist">
|
|
<div role="tab" aria-selected="true"><b>Tab1</b></div>
|
|
<div role="tab">Tab2</div>
|
|
</div>`);
|
|
const golden = {
|
|
role: FFOX ? 'document' : 'WebArea',
|
|
name: '',
|
|
children: [{
|
|
role: 'tab',
|
|
name: 'Tab1',
|
|
selected: true
|
|
}, {
|
|
role: 'tab',
|
|
name: 'Tab2'
|
|
}]
|
|
};
|
|
expect(await page.accessibility.snapshot()).toEqual(golden);
|
|
});
|
|
|
|
// WebKit rich text accessibility is iffy
|
|
it.skip(WEBKIT)('rich text editable fields should have children', async function({page}) {
|
|
await page.setContent(`
|
|
<div contenteditable="true">
|
|
Edit this image: <img src="fakeimage.png" alt="my fake image">
|
|
</div>`);
|
|
const golden = FFOX ? {
|
|
role: 'section',
|
|
name: '',
|
|
children: [{
|
|
role: 'text leaf',
|
|
name: 'Edit this image: '
|
|
}, {
|
|
role: 'text',
|
|
name: 'my fake image'
|
|
}]
|
|
} : {
|
|
role: 'generic',
|
|
name: '',
|
|
value: 'Edit this image: ',
|
|
children: [{
|
|
role: 'text',
|
|
name: 'Edit this image:'
|
|
}, {
|
|
role: 'img',
|
|
name: 'my fake image'
|
|
}]
|
|
};
|
|
const snapshot = await page.accessibility.snapshot();
|
|
expect(snapshot.children[0]).toEqual(golden);
|
|
});
|
|
// WebKit rich text accessibility is iffy
|
|
it.skip(WEBKIT)('rich text editable fields with role should have children', async function({page}) {
|
|
await page.setContent(`
|
|
<div contenteditable="true" role='textbox'>
|
|
Edit this image: <img src="fakeimage.png" alt="my fake image">
|
|
</div>`);
|
|
const golden = FFOX ? {
|
|
role: 'textbox',
|
|
name: '',
|
|
value: 'Edit this image: my fake image',
|
|
children: [{
|
|
role: 'text',
|
|
name: 'my fake image'
|
|
}]
|
|
} : {
|
|
role: 'textbox',
|
|
name: '',
|
|
value: 'Edit this image: ',
|
|
children: [{
|
|
role: 'text',
|
|
name: 'Edit this image:'
|
|
}, {
|
|
role: 'img',
|
|
name: 'my fake image'
|
|
}]
|
|
};
|
|
const snapshot = await page.accessibility.snapshot();
|
|
expect(snapshot.children[0]).toEqual(golden);
|
|
});
|
|
|
|
it.skip(FFOX || WEBKIT)('plain text field with role should not have children', async function({page}) {
|
|
// Firefox does not support contenteditable="plaintext-only".
|
|
// WebKit rich text accessibility is iffy
|
|
await page.setContent(`
|
|
<div contenteditable="plaintext-only" role='textbox'>Edit this image:<img src="fakeimage.png" alt="my fake image"></div>`);
|
|
const snapshot = await page.accessibility.snapshot();
|
|
expect(snapshot.children[0]).toEqual({
|
|
role: 'textbox',
|
|
name: '',
|
|
value: 'Edit this image:'
|
|
});
|
|
});
|
|
|
|
it.skip(FFOX || WEBKIT)('plain text field without role should not have content', async function({page}) {
|
|
await page.setContent(`
|
|
<div contenteditable="plaintext-only">Edit this image:<img src="fakeimage.png" alt="my fake image"></div>`);
|
|
const snapshot = await page.accessibility.snapshot();
|
|
expect(snapshot.children[0]).toEqual({
|
|
role: 'generic',
|
|
name: ''
|
|
});
|
|
});
|
|
|
|
it.skip(FFOX || WEBKIT)('plain text field with tabindex and without role should not have content', async function({page}) {
|
|
await page.setContent(`
|
|
<div contenteditable="plaintext-only" tabIndex=0>Edit this image:<img src="fakeimage.png" alt="my fake image"></div>`);
|
|
const snapshot = await page.accessibility.snapshot();
|
|
expect(snapshot.children[0]).toEqual({
|
|
role: 'generic',
|
|
name: ''
|
|
});
|
|
});
|
|
|
|
it('non editable textbox with role and tabIndex and label should not have children', async function({page}) {
|
|
await page.setContent(`
|
|
<div role="textbox" tabIndex=0 aria-checked="true" aria-label="my favorite textbox">
|
|
this is the inner content
|
|
<img alt="yo" src="fakeimg.png">
|
|
</div>`);
|
|
const golden = FFOX ? {
|
|
role: 'textbox',
|
|
name: 'my favorite textbox',
|
|
value: 'this is the inner content yo'
|
|
} : CHROMIUM ? {
|
|
role: 'textbox',
|
|
name: 'my favorite textbox',
|
|
value: 'this is the inner content '
|
|
} : {
|
|
role: 'textbox',
|
|
name: 'my favorite textbox',
|
|
value: 'this is the inner content ',
|
|
};
|
|
const snapshot = await page.accessibility.snapshot();
|
|
expect(snapshot.children[0]).toEqual(golden);
|
|
});
|
|
|
|
it('checkbox with and tabIndex and label should not have children', async function({page}) {
|
|
await page.setContent(`
|
|
<div role="checkbox" tabIndex=0 aria-checked="true" aria-label="my favorite checkbox">
|
|
this is the inner content
|
|
<img alt="yo" src="fakeimg.png">
|
|
</div>`);
|
|
const golden = {
|
|
role: 'checkbox',
|
|
name: 'my favorite checkbox',
|
|
checked: true
|
|
};
|
|
const snapshot = await page.accessibility.snapshot();
|
|
expect(snapshot.children[0]).toEqual(golden);
|
|
});
|
|
|
|
it('checkbox without label should not have children', async function({page}) {
|
|
await page.setContent(`
|
|
<div role="checkbox" aria-checked="true">
|
|
this is the inner content
|
|
<img alt="yo" src="fakeimg.png">
|
|
</div>`);
|
|
const golden = FFOX ? {
|
|
role: 'checkbox',
|
|
name: 'this is the inner content yo',
|
|
checked: true
|
|
} : {
|
|
role: 'checkbox',
|
|
name: 'this is the inner content yo',
|
|
checked: true
|
|
};
|
|
const snapshot = await page.accessibility.snapshot();
|
|
expect(snapshot.children[0]).toEqual(golden);
|
|
});
|
|
|
|
it('should work a button', async({page}) => {
|
|
await page.setContent(`<button>My Button</button>`);
|
|
|
|
const button = await page.$('button');
|
|
expect(await page.accessibility.snapshot({root: button})).toEqual({
|
|
role: 'button',
|
|
name: 'My Button'
|
|
});
|
|
});
|
|
|
|
it('should work an input', async({page}) => {
|
|
await page.setContent(`<input title="My Input" value="My Value">`);
|
|
|
|
const input = await page.$('input');
|
|
expect(await page.accessibility.snapshot({root: input})).toEqual({
|
|
role: 'textbox',
|
|
name: 'My Input',
|
|
value: 'My Value'
|
|
});
|
|
});
|
|
|
|
it('should work on a menu', async({page}) => {
|
|
await page.setContent(`
|
|
<div role="menu" title="My Menu">
|
|
<div role="menuitem">First Item</div>
|
|
<div role="menuitem">Second Item</div>
|
|
<div role="menuitem">Third Item</div>
|
|
</div>
|
|
`);
|
|
|
|
const menu = await page.$('div[role="menu"]');
|
|
expect(await page.accessibility.snapshot({root: menu})).toEqual({
|
|
role: 'menu',
|
|
name: 'My Menu',
|
|
children:
|
|
[ { role: 'menuitem', name: 'First Item' },
|
|
{ role: 'menuitem', name: 'Second Item' },
|
|
{ role: 'menuitem', name: 'Third Item' } ],
|
|
orientation: WEBKIT ? 'vertical' : undefined
|
|
});
|
|
});
|
|
|
|
it('should return null when the element is no longer in DOM', async({page}) => {
|
|
await page.setContent(`<button>My Button</button>`);
|
|
const button = await page.$('button');
|
|
await page.$eval('button', button => button.remove());
|
|
expect(await page.accessibility.snapshot({root: button})).toEqual(null);
|
|
});
|
|
|
|
it('should show uninteresting nodes', async({page}) => {
|
|
await page.setContent(`
|
|
<div id="root" role="textbox">
|
|
<div>
|
|
hello
|
|
<div>
|
|
world
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`);
|
|
|
|
const root = await page.$('#root');
|
|
const snapshot = await page.accessibility.snapshot({root, interestingOnly: false});
|
|
expect(snapshot.role).toBe('textbox');
|
|
expect(snapshot.value).toContain('hello');
|
|
expect(snapshot.value).toContain('world');
|
|
expect(!!snapshot.children).toBe(true);
|
|
});
|
|
|
|
it('should work when there is a title ', async ({page}) => {
|
|
await page.setContent(`
|
|
<title>This is the title</title>
|
|
<div>This is the content</div>
|
|
`);
|
|
const snapshot = await page.accessibility.snapshot();
|
|
expect(snapshot.name).toBe('This is the title');
|
|
expect(snapshot.children[0].name).toBe('This is the content');
|
|
});
|