Skip to content

Commit 8f6ae76

Browse files
authored
fix: use @testing-library/dom native methods for suggestion btns (#150)
1 parent 4dc963b commit 8f6ae76

File tree

12 files changed

+226
-117
lines changed

12 files changed

+226
-117
lines changed

devtools/src/devtools/components/MenuBar.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ function MenuBar({ cssPath, suggestion }) {
3737
className="focus:outline-none"
3838
title="Inspect the matching DOM element"
3939
disabled={!cssPath}
40-
onClick={() => inspectedWindow.inspect(cssPath)}
40+
onClick={() => inspectedWindow.inspect(cssPath.toString())}
4141
>
4242
<InspectIcon />
4343
</button>

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"postversion": "git push && git push --tags && git checkout master && git merge develop --ff && git push && git checkout -"
3939
},
4040
"dependencies": {
41-
"@testing-library/dom": "^7.12.0",
41+
"@testing-library/dom": "^7.15.0",
4242
"codemirror": "5.54.0",
4343
"crx-bridge": "^2.1.0",
4444
"deep-diff": "^1.0.2",

src/components/Result.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import ErrorBox from './ErrorBox';
33
import ResultQueries from './ResultQueries';
44
import ResultSuggestion from './ResultSuggestion';
55
import Scrollable from './Scrollable';
6-
import { emptyResult } from '../lib';
76

87
function Result({ result, dispatch }) {
98
if (result.error) {
@@ -37,9 +36,7 @@ function Result({ result, dispatch }) {
3736
</div>
3837
);
3938
}
40-
41-
const { data, suggestion } = result.elements?.[0] || emptyResult;
42-
39+
const { data, suggestion, queries } = result.elements[0];
4340
return (
4441
<div className="flex flex-col w-full h-full overflow-hidden">
4542
<div className="flex-none pb-4 border-b">
@@ -55,6 +52,7 @@ function Result({ result, dispatch }) {
5552
<Scrollable>
5653
<ResultQueries
5754
data={data}
55+
possibleQueries={queries}
5856
suggestion={suggestion}
5957
activeMethod={result.expression?.method}
6058
dispatch={dispatch}

src/components/ResultQueries.js

Lines changed: 58 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,30 @@
11
import React from 'react';
2-
import { getExpression, getFieldName } from '../lib';
2+
import { getFieldName } from '../lib';
3+
import { queries } from '../constants';
34

45
function Section({ children }) {
56
return <div className="space-y-3">{children}</div>;
67
}
78

89
function Heading({ children }) {
9-
return <h3 className="font-bold text-xs">{children}</h3>;
10+
return <h3 className="text-xs font-bold">{children}</h3>;
1011
}
1112

12-
const Field = React.memo(function Field({ method, data, dispatch, active }) {
13+
const Field = React.memo(function Field({
14+
data,
15+
method,
16+
query,
17+
dispatch,
18+
active,
19+
}) {
1320
const field = getFieldName(method);
1421
const value = data[field];
15-
1622
const handleClick = value
1723
? () => {
18-
const expression = getExpression({ method, data });
19-
dispatch({ type: 'SET_QUERY', query: expression });
24+
dispatch({
25+
type: 'SET_QUERY',
26+
query: `screen.${query.toString()}`,
27+
});
2028
}
2129
: undefined;
2230

@@ -26,7 +34,7 @@ const Field = React.memo(function Field({ method, data, dispatch, active }) {
2634
data-clickable={!!handleClick}
2735
onClick={handleClick}
2836
>
29-
<div className="text-gray-800 font-light">{field}</div>
37+
<div className="font-light text-gray-800">{field}</div>
3038
<div className="truncate">
3139
{value || <span className="text-gray-400">n/a</span>}
3240
</div>
@@ -35,68 +43,62 @@ const Field = React.memo(function Field({ method, data, dispatch, active }) {
3543
});
3644

3745
// for inputs, the role will only work if there is also a type attribute
38-
function ResultQueries({ data, dispatch, activeMethod }) {
46+
function ResultQueries({ data, possibleQueries, dispatch, activeMethod }) {
3947
return (
4048
<div className="grid grid-cols-2 gap-4 pt-4">
4149
<Section>
4250
<Heading>1. Queries Accessible to Everyone</Heading>
43-
<Field
44-
method="getByRole"
45-
data={data}
46-
dispatch={dispatch}
47-
active={'getByRole' === activeMethod}
48-
/>
49-
<Field
50-
method="getByLabelText"
51-
data={data}
52-
dispatch={dispatch}
53-
active={'getByLabelText' === activeMethod}
54-
/>
55-
<Field
56-
method="getByPlaceholderText"
57-
data={data}
58-
dispatch={dispatch}
59-
active={'getByPlaceholderText' === activeMethod}
60-
/>
61-
<Field
62-
method="getByText"
63-
data={data}
64-
dispatch={dispatch}
65-
active={'getByText' === activeMethod}
66-
/>
67-
<Field
68-
method="getByDisplayValue"
69-
data={data}
70-
dispatch={dispatch}
71-
active={'getByDisplayValue' === activeMethod}
72-
/>
51+
{queries
52+
.filter((query) => query.type === 'ACCESSIBLE')
53+
.map((query) => {
54+
return (
55+
<Field
56+
key={query.method}
57+
data={data}
58+
method={query.method}
59+
query={possibleQueries[query.method]}
60+
dispatch={dispatch}
61+
active={query.method === activeMethod}
62+
/>
63+
);
64+
})}
7365
</Section>
7466

7567
<div className="space-y-8">
7668
<Section>
7769
<Heading>2. Semantic Queries</Heading>
78-
<Field
79-
method="getByAltText"
80-
data={data}
81-
dispatch={dispatch}
82-
active={'getByAltText' === activeMethod}
83-
/>
84-
<Field
85-
method="getByTitle"
86-
data={data}
87-
dispatch={dispatch}
88-
active={'getByTitle' === activeMethod}
89-
/>
70+
{queries
71+
.filter((query) => query.type === 'SEMANTIC')
72+
.map((query) => {
73+
return (
74+
<Field
75+
key={query.method}
76+
data={data}
77+
method={query.method}
78+
query={possibleQueries[query.method]}
79+
dispatch={dispatch}
80+
active={query.method === activeMethod}
81+
/>
82+
);
83+
})}
9084
</Section>
9185

9286
<Section>
9387
<Heading>3. TestId</Heading>
94-
<Field
95-
method="getByTestId"
96-
data={data}
97-
dispatch={dispatch}
98-
active={'getByTestId' === activeMethod}
99-
/>
88+
{queries
89+
.filter((query) => query.type === 'TEST')
90+
.map((query) => {
91+
return (
92+
<Field
93+
key={query.method}
94+
data={data}
95+
method={query.method}
96+
query={possibleQueries[query.method]}
97+
dispatch={dispatch}
98+
active={query.method === activeMethod}
99+
/>
100+
);
101+
})}
100102
</Section>
101103
</div>
102104
</div>

src/constants.js

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,22 @@ screen.getByRole('button')
2525
};
2626

2727
export const queries = [
28-
{ method: 'getByRole', level: 0 },
29-
{ method: 'getByLabelText', level: 0 },
30-
{ method: 'getByPlaceholderText', level: 0 },
31-
{ method: 'getByText', level: 0 },
32-
{ method: 'getByDisplayValue', level: 0 },
28+
{ method: 'getByRole', level: 0, type: 'ACCESSIBLE' },
29+
{ method: 'getByLabelText', level: 0, type: 'ACCESSIBLE' },
30+
{
31+
method: 'getByPlaceholderText',
32+
level: 0,
33+
type: 'ACCESSIBLE',
34+
},
35+
{ method: 'getByText', level: 0, type: 'ACCESSIBLE' },
36+
{ method: 'getByDisplayValue', level: 0, type: 'ACCESSIBLE' },
3337

34-
{ method: 'getByAltText', level: 1 },
35-
{ method: 'getByTitle', level: 1 },
38+
{ method: 'getByAltText', level: 1, type: 'SEMANTIC' },
39+
{ method: 'getByTitle', level: 1, type: 'SEMANTIC' },
3640

37-
{ method: 'getByTestId', level: 2 },
41+
{ method: 'getByTestId', level: 2, type: 'TEST' },
3842

39-
{ method: 'querySelector', level: 3 },
43+
{ method: 'querySelector', level: 3, type: 'GENERIC' },
4044
];
4145

4246
// some quotes from https://testing-library.com/docs/guide-which-query

src/lib/getExpression.js

Lines changed: 0 additions & 41 deletions
This file was deleted.

src/lib/getFieldName.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
export function wrapInQuotes(val) {
2+
if (!val.includes(`'`)) {
3+
return `'${val}'`;
4+
}
5+
6+
if (!val.includes('"')) {
7+
return `"${val}"`;
8+
}
9+
10+
if (!val.includes('`')) {
11+
return `\`${val}\``;
12+
}
13+
14+
return `'${val.replace(/'/g, `\\'`)}'`;
15+
}
16+
17+
export function getFieldName(method) {
18+
return method[5].toLowerCase() + method.substr(6);
19+
}

src/lib/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
export * from './ensureArray';
2-
export * from './getExpression';
2+
export * from './getFieldName';
33
export * from './queryAdvise';

src/lib/queryAdvise.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { messages, queries } from '../constants';
22
import { computeAccessibleName, getRole } from 'dom-accessibility-api';
33
import { getSuggestedQuery } from '@testing-library/dom';
44
import cssPath from './cssPath';
5+
import { getFieldName } from './';
56

67
export function getData({ rootNode, element }) {
78
const type = element.getAttribute('type');
@@ -80,3 +81,19 @@ export function getQueryAdvise({ rootNode, element }) {
8081
suggestion,
8182
};
8283
}
84+
85+
export function getAllPossibileQueries(element) {
86+
const possibleQueries = queries
87+
.filter((query) => query.type !== 'GENERIC')
88+
.map((query) => {
89+
const method = getFieldName(query.method);
90+
return getSuggestedQuery(element, 'get', method);
91+
})
92+
.filter((suggestedQuery) => suggestedQuery !== undefined)
93+
.reduce((obj, suggestedQuery) => {
94+
obj[suggestedQuery.queryMethod] = suggestedQuery;
95+
return obj;
96+
}, {});
97+
98+
return possibleQueries;
99+
}

0 commit comments

Comments
 (0)