Skip to content

Commit 77533e8

Browse files
committed
test: use role based selectors in trace-viewer tests
1 parent 0c5d3f2 commit 77533e8

10 files changed

Lines changed: 48 additions & 43 deletions

File tree

packages/trace-viewer/src/ui/logTab.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export const LogTab: React.FunctionComponent<{
5858

5959
return <LogList
6060
name='log'
61+
ariaLabel='Log entries'
6162
items={entries}
6263
render={entry => <div className='log-list-item'>
6364
<span className='log-list-duration'>{entry.time}</span>

packages/trace-viewer/src/ui/metadataView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export const MetadataView: React.FunctionComponent<{
2727

2828
const wallTime = model.wallTime !== undefined ? new Date(model.wallTime).toLocaleString(undefined, { timeZoneName: 'short' }) : undefined;
2929

30-
return <div data-testid='metadata-view' className='vbox' style={{ flexShrink: 0 }}>
30+
return <div className='vbox' style={{ flexShrink: 0 }}>
3131
<div className='call-section' style={{ paddingTop: 2 }}>Time</div>
3232
{!!wallTime && <div className='call-line'>start time:<span className='call-value datetime' title={wallTime}>{wallTime}</span></div>}
3333
<div className='call-line'>duration:<span className='call-value number' title={msToString(model.endTime - model.startTime)}>{msToString(model.endTime - model.startTime)}</span></div>

packages/trace-viewer/src/ui/networkTab.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ export const NetworkTab: React.FunctionComponent<{
9494

9595
const grid = <NetworkGridView
9696
name='network'
97+
ariaLabel='Network requests'
9798
items={renderedEntries}
9899
selectedItem={selectedEntry}
99100
onSelected={item => setSelectedEntry(item)}

packages/trace-viewer/src/ui/stackTrace.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export const StackTraceView: React.FunctionComponent<{
2929
const frames = stack || [];
3030
return <StackFrameListView
3131
name='stack-trace'
32+
ariaLabel='Stack trace'
3233
items={frames}
3334
selectedItem={frames[selectedFrame]}
3435
render={frame => {

packages/web/src/components/gridView.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ export function GridView<T>(model: GridViewProps<T>) {
9292
<ListView
9393
name={model.name}
9494
items={model.items}
95+
ariaLabel={model.ariaLabel}
9596
id={model.id}
9697
render={(item, index) => {
9798
return <>

packages/web/src/components/listView.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export type ListViewProps<T> = {
2727
isError?: (item: T, index: number) => boolean,
2828
isWarning?: (item: T, index: number) => boolean,
2929
isInfo?: (item: T, index: number) => boolean,
30+
ariaLabel?: string,
3031
selectedItem?: T,
3132
onAccepted?: (item: T, index: number) => void,
3233
onSelected?: (item: T, index: number) => void,
@@ -56,6 +57,7 @@ export function ListView<T>({
5657
noItemsMessage,
5758
dataTestId,
5859
notSelectable,
60+
ariaLabel,
5961
}: ListViewProps<T>) {
6062
const itemListRef = React.useRef<HTMLDivElement>(null);
6163
const [highlightedItem, setHighlightedItem] = React.useState<any>();
@@ -80,7 +82,7 @@ export function ListView<T>({
8082
itemListRef.current.scrollTop = scrollPositions.get(name) || 0;
8183
}, [name]);
8284

83-
return <div className={clsx(`list-view vbox`, name + '-list-view')} role={items.length > 0 ? 'list' : undefined} data-testid={dataTestId || (name + '-list')}>
85+
return <div className={clsx(`list-view vbox`, name + '-list-view')} role={items.length > 0 ? 'list' : undefined} aria-label={ariaLabel}>
8486
<div
8587
className={clsx('list-view-content', notSelectable && 'not-selectable')}
8688
tabIndex={0}
@@ -132,6 +134,7 @@ export function ListView<T>({
132134
isError?.(item, index) && 'error',
133135
isWarning?.(item, index) && 'warning',
134136
isInfo?.(item, index) && 'info')}
137+
aria-selected={selectedItem === item}
135138
onClick={() => onSelected?.(item, index)}
136139
onMouseEnter={() => setHighlightedItem(item)}
137140
onMouseLeave={() => setHighlightedItem(undefined)}

tests/config/traceViewerFixtures.ts

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -57,74 +57,73 @@ class TraceViewerPage {
5757
this.actionTitles = page.locator('.action-title');
5858
this.actionsTree = page.getByTestId('actions-tree');
5959
this.callLines = page.locator('.call-tab .call-line');
60-
this.logLines = page.getByTestId('log-list').locator('.list-view-entry');
61-
this.consoleLines = page.locator('.console-line');
60+
this.logLines = page.getByRole('list', { name: 'Log entries' }).getByRole('listitem');
61+
this.consoleLines = page.getByRole('tabpanel', { name: 'Console' }).getByRole('listitem');
6262
this.consoleLineMessages = page.locator('.console-line-message');
6363
this.errorMessages = page.locator('.error-message');
6464
this.consoleStacks = page.locator('.console-stack');
65-
this.stackFrames = page.getByTestId('stack-trace-list').locator('.list-view-entry');
66-
this.networkRequests = page.getByTestId('network-list').locator('.list-view-entry');
65+
this.stackFrames = page.getByRole('list', { name: 'Stack trace' }).getByRole('listitem');
66+
this.networkRequests = page.getByRole('list', { name: 'Network requests' }).getByRole('listitem');
6767
this.snapshotContainer = page.locator('.snapshot-container iframe.snapshot-visible[name=snapshot]');
68-
this.metadataTab = page.getByTestId('metadata-view');
69-
this.sourceCodeTab = page.getByTestId('source-code');
68+
this.metadataTab = page.getByRole('tabpanel', { name: 'Metadata' });
69+
this.sourceCodeTab = page.getByRole('tabpanel', { name: 'Source' });
7070

7171
this.settingsDialog = page.getByTestId('settings-toolbar-dialog');
7272
this.darkModeSetting = page.locator('.setting').getByText('Dark mode');
7373
this.displayCanvasContentSetting = page.locator('.setting').getByText('Display canvas content');
7474
}
7575

76-
async actionIconsText(action: string) {
77-
const entry = await this.page.waitForSelector(`.tree-view-entry:has-text("${action}")`);
78-
await entry.waitForSelector('.action-icon-value:visible');
79-
return await entry.$$eval('.action-icon-value:visible', ee => ee.map(e => e.textContent));
76+
actionIconsText(action: string) {
77+
const entry = this.actionsTree.getByRole('treeitem', { name: action });
78+
return entry.locator('.action-icon-value').filter({ visible: true });
8079
}
8180

82-
async actionIcons(action: string) {
83-
return await this.page.waitForSelector(`.tree-view-entry:has-text("${action}") .action-icons`);
81+
actionIcons(action: string) {
82+
return this.actionsTree.getByRole('treeitem', { name: action }).locator('.action-icons').filter({ visible: true });
8483
}
8584

8685
@step
87-
async expandAction(title: string, ordinal: number = 0) {
88-
await this.actionsTree.locator('.tree-view-entry', { hasText: title }).nth(ordinal).locator('.codicon-chevron-right').click();
86+
async expandAction(title: string) {
87+
await this.actionsTree.getByRole('treeitem', { name: title }).locator('.codicon-chevron-right').click();
8988
}
9089

9190
@step
9291
async selectAction(title: string, ordinal: number = 0) {
93-
await this.page.locator(`.action-title:has-text("${title}")`).nth(ordinal).click();
92+
await this.actionsTree.getByTitle(title).nth(ordinal).click();
9493
}
9594

9695
@step
9796
async hoverAction(title: string, ordinal: number = 0) {
98-
await this.page.locator(`.action-title:has-text("${title}")`).nth(ordinal).hover();
97+
await this.actionTitles.filter({ hasText: title }).nth(ordinal).hover();
9998
}
10099

101100
@step
102101
async selectSnapshot(name: string) {
103-
await this.page.click(`.snapshot-tab .tabbed-pane-tab-label:has-text("${name}")`);
102+
await this.page.getByRole('tab', { name }).click();
104103
}
105104

106105
async showErrorsTab() {
107-
await this.page.click('text="Errors"');
106+
await this.page.getByRole('tab', { name: 'Errors' }).click();
108107
}
109108

110109
async showConsoleTab() {
111-
await this.page.click('text="Console"');
110+
await this.page.getByRole('tab', { name: 'Console' }).click();
112111
}
113112

114113
async showSourceTab() {
115-
await this.page.click('text="Source"');
114+
await this.page.getByRole('tab', { name: 'Source' }).click();
116115
}
117116

118117
async showNetworkTab() {
119-
await this.page.click('text="Network"');
118+
await this.page.getByRole('tab', { name: 'Network' }).click();
120119
}
121120

122121
async showMetadataTab() {
123-
await this.page.click('text="Metadata"');
122+
await this.page.getByRole('tab', { name: 'Metadata' }).click();
124123
}
125124

126125
async showSettings() {
127-
await this.page.locator('.settings-gear').click();
126+
await this.page.getByRole('button', { name: 'Settings' }).click();
128127
}
129128

130129
@step

tests/library/trace-viewer.spec.ts

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -282,12 +282,12 @@ test('should render console', async ({ showTraceViewer, browserName }) => {
282282
await expect(listViews.filter({ hasText: 'Cheers!' })).toHaveClass('list-view-entry');
283283
});
284284

285-
test('should open console errors on click', async ({ showTraceViewer, browserName }) => {
285+
test('should open console errors on click', async ({ showTraceViewer }) => {
286286
const traceViewer = await showTraceViewer([traceFile]);
287-
expect(await traceViewer.actionIconsText('Evaluate')).toEqual(['2', '1']);
288-
expect(await traceViewer.page.isHidden('.console-tab')).toBeTruthy();
289-
await (await traceViewer.actionIcons('Evaluate')).click();
290-
expect(await traceViewer.page.waitForSelector('.console-tab')).toBeTruthy();
287+
await expect(traceViewer.actionIconsText('Evaluate')).toHaveText(['2', '1']);
288+
await expect(traceViewer.page.getByRole('tabpanel', { name: 'Console' })).toBeHidden();
289+
await traceViewer.actionIcons('Evaluate').click();
290+
await traceViewer.page.getByRole('tabpanel', { name: 'Console' }).waitFor();
291291
});
292292

293293
test('should show params and return value', async ({ showTraceViewer }) => {
@@ -977,14 +977,13 @@ test('should highlight expect failure', async ({ page, server, runAndTrace }) =>
977977
test('should show action source', async ({ showTraceViewer }) => {
978978
const traceViewer = await showTraceViewer([traceFile]);
979979
await traceViewer.selectAction('Click');
980-
const page = traceViewer.page;
981980

982-
await page.click('text=Source');
983-
await expect(page.locator('.source-line-running')).toContainText('await page.getByText(\'Click\').click()');
984-
await expect(page.getByTestId('stack-trace-list').locator('.list-view-entry.selected')).toHaveText(/doClick.*trace-viewer\.spec\.ts:[\d]+/);
981+
await traceViewer.showSourceTab();
982+
await expect(traceViewer.page.locator('.source-line-running')).toContainText('await page.getByText(\'Click\').click()');
983+
await expect(traceViewer.stackFrames.and(traceViewer.page.locator('.selected'))).toHaveText(/doClick.*trace-viewer\.spec\.ts:[\d]+/);
985984

986985
await traceViewer.hoverAction('Wait for navigation');
987-
await expect(page.locator('.source-line-running')).toContainText('page.waitForNavigation()');
986+
await expect(traceViewer.page.locator('.source-line-running')).toContainText('page.waitForNavigation()');
988987
});
989988

990989
test('should follow redirects', async ({ page, runAndTrace, server, asset }) => {
@@ -1015,7 +1014,7 @@ test('should follow redirects', async ({ page, runAndTrace, server, asset }) =>
10151014

10161015
test('should include metainfo', async ({ showTraceViewer }) => {
10171016
const traceViewer = await showTraceViewer([traceFile]);
1018-
await traceViewer.page.locator('text=Metadata').click();
1017+
await traceViewer.page.getByRole('tab', { name: 'Metadata' }).click();
10191018
const callLine = traceViewer.metadataTab.locator('.call-line');
10201019
await expect(callLine.getByText('start time')).toHaveText(/start time:[\d/,: ]+/);
10211020
await expect(callLine.getByText('duration')).toHaveText(/duration:[\dms]+/);
@@ -1065,7 +1064,7 @@ test('should open two trace files', async ({ context, page, request, server, sho
10651064
/Fetch "\/one-style\.css"/,
10661065
]);
10671066

1068-
await traceViewer.page.locator('text=Metadata').click();
1067+
await traceViewer.page.getByRole('tab', { name: 'Metadata' }).click();
10691068
const callLine = traceViewer.page.locator('.call-line');
10701069
// Should get metadata from the context trace
10711070
await expect(callLine.getByText('start time')).toHaveText(/start time:[\d/,: ]+/);

tests/playwright-test/reporter-html.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -518,18 +518,18 @@ for (const useIntermediateMergeReport of [true, false] as const) {
518518
await page.getByRole('link', { name: 'passes' }).click();
519519
await page.click('img');
520520
await page.click('.action-title >> text=EVALUATE');
521-
await page.click('text=Source');
521+
await page.getByRole('tab', { name: 'Source' }).click();
522522

523523
await expect(page.locator('.CodeMirror-line')).toContainText([
524524
/import.*test/,
525525
/page\.evaluate/
526526
]);
527527
await expect(page.locator('.source-line-running')).toContainText('page.evaluate');
528528

529-
await expect(page.getByTestId('stack-trace-list')).toContainText([
529+
await expect(page.getByRole('list', { name: 'Stack trace' }).getByRole('listitem')).toContainText([
530530
/a.test.js:[\d]+/,
531531
]);
532-
await expect(page.getByTestId('stack-trace-list').locator('.list-view-entry.selected')).toContainText('a.test.js');
532+
await expect(page.getByRole('list', { name: 'Stack trace' }).getByRole('listitem').and(page.locator('.selected'))).toContainText('a.test.js');
533533
});
534534

535535
test('should not show stack trace', async ({ runInlineTest, page, showReport }) => {

tests/playwright-test/ui-mode-test-network-tab.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ test('should filter network requests by resource type', async ({ runUITest, serv
3232
await page.getByText('network tab test').dblclick();
3333
await page.getByText('Network', { exact: true }).click();
3434

35-
const networkItems = page.getByTestId('network-list').getByRole('listitem');
35+
const networkItems = page.getByRole('list', { name: 'Network requests' }).getByRole('listitem');
3636

3737
await page.getByText('JS', { exact: true }).click();
3838
await expect(networkItems).toHaveCount(1);
@@ -73,7 +73,7 @@ test('should filter network requests by url', async ({ runUITest, server }) => {
7373
await page.getByText('network tab test').dblclick();
7474
await page.getByText('Network', { exact: true }).click();
7575

76-
const networkItems = page.getByTestId('network-list').getByRole('listitem');
76+
const networkItems = page.getByRole('list', { name: 'Network requests' }).getByRole('listitem');
7777

7878
await page.getByPlaceholder('Filter network').fill('script.');
7979
await expect(networkItems).toHaveCount(1);
@@ -198,5 +198,5 @@ test('should not duplicate network entries from beforeAll', {
198198

199199
await page.getByText('first test').dblclick();
200200
await page.getByText('Network', { exact: true }).click();
201-
await expect(page.getByTestId('network-list').getByText('empty.html')).toHaveCount(1);
201+
await expect(page.getByRole('list', { name: 'Network requests' }).getByText('empty.html')).toHaveCount(1);
202202
});

0 commit comments

Comments
 (0)