chore: bump ESLint to version 8 (#10433)
This commit is contained in:
parent
e76edef3e2
commit
b8b0d7139c
900
package-lock.json
generated
900
package-lock.json
generated
File diff suppressed because it is too large
Load diff
10
package.json
10
package.json
|
|
@ -21,7 +21,7 @@
|
||||||
"ttest": "node ./tests/playwright-test/stable-test-runner/node_modules/@playwright/test/cli test --config=tests/playwright-test/playwright-test.config.ts",
|
"ttest": "node ./tests/playwright-test/stable-test-runner/node_modules/@playwright/test/cli test --config=tests/playwright-test/playwright-test.config.ts",
|
||||||
"vtest": "cross-env PLAYWRIGHT_DOCKER=1 node ./tests/playwright-test/stable-test-runner/node_modules/@playwright/test/cli test --config=tests/playwright-test/playwright-test.config.ts",
|
"vtest": "cross-env PLAYWRIGHT_DOCKER=1 node ./tests/playwright-test/stable-test-runner/node_modules/@playwright/test/cli test --config=tests/playwright-test/playwright-test.config.ts",
|
||||||
"test": "playwright test --config=tests/config/default.config.ts",
|
"test": "playwright test --config=tests/config/default.config.ts",
|
||||||
"eslint": "eslint -f codeframe --ext ts,tsx .",
|
"eslint": "eslint --ext ts,tsx .",
|
||||||
"tsc": "tsc -p .",
|
"tsc": "tsc -p .",
|
||||||
"build-installer": "babel -s --extensions \".ts\" --out-dir packages/playwright-core/lib/utils/ packages/playwright-core/src/utils",
|
"build-installer": "babel -s --extensions \".ts\" --out-dir packages/playwright-core/lib/utils/ packages/playwright-core/src/utils",
|
||||||
"doc": "node utils/doclint/cli.js",
|
"doc": "node utils/doclint/cli.js",
|
||||||
|
|
@ -67,8 +67,8 @@
|
||||||
"@types/ws": "7.2.6",
|
"@types/ws": "7.2.6",
|
||||||
"@types/xml2js": "^0.4.5",
|
"@types/xml2js": "^0.4.5",
|
||||||
"@types/yazl": "^2.4.2",
|
"@types/yazl": "^2.4.2",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.31.2",
|
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||||
"@typescript-eslint/parser": "^4.31.2",
|
"@typescript-eslint/parser": "^5.4.0",
|
||||||
"@vercel/ncc": "^0.31.1",
|
"@vercel/ncc": "^0.31.1",
|
||||||
"@zip.js/zip.js": "^2.3.17",
|
"@zip.js/zip.js": "^2.3.17",
|
||||||
"ansi-to-html": "^0.7.1",
|
"ansi-to-html": "^0.7.1",
|
||||||
|
|
@ -81,9 +81,9 @@
|
||||||
"css-loader": "^6.4.0",
|
"css-loader": "^6.4.0",
|
||||||
"electron": "^12.2.1",
|
"electron": "^12.2.1",
|
||||||
"enquirer": "^2.3.6",
|
"enquirer": "^2.3.6",
|
||||||
"eslint": "^7.31.0",
|
"eslint": "^8.2.0",
|
||||||
"eslint-plugin-notice": "^0.9.10",
|
"eslint-plugin-notice": "^0.9.10",
|
||||||
"eslint-plugin-react-hooks": "^4.2.0",
|
"eslint-plugin-react-hooks": "^4.3.0",
|
||||||
"file-loader": "^6.2.0",
|
"file-loader": "^6.2.0",
|
||||||
"formidable": "^1.2.2",
|
"formidable": "^1.2.2",
|
||||||
"html-webpack-plugin": "^5.3.2",
|
"html-webpack-plugin": "^5.3.2",
|
||||||
|
|
|
||||||
|
|
@ -54,216 +54,216 @@ const WKUnhelpfulRoleDescriptions = new Map(Object.entries({
|
||||||
}));
|
}));
|
||||||
|
|
||||||
class WKAXNode implements accessibility.AXNode {
|
class WKAXNode implements accessibility.AXNode {
|
||||||
private _payload: Protocol.Page.AXNode;
|
private _payload: Protocol.Page.AXNode;
|
||||||
private _children: WKAXNode[];
|
private _children: WKAXNode[];
|
||||||
|
|
||||||
constructor(payload: Protocol.Page.AXNode) {
|
constructor(payload: Protocol.Page.AXNode) {
|
||||||
this._payload = payload;
|
this._payload = payload;
|
||||||
|
|
||||||
this._children = [];
|
this._children = [];
|
||||||
for (const payload of this._payload.children || [])
|
for (const payload of this._payload.children || [])
|
||||||
this._children.push(new WKAXNode(payload));
|
this._children.push(new WKAXNode(payload));
|
||||||
|
}
|
||||||
|
|
||||||
|
children() {
|
||||||
|
return this._children;
|
||||||
|
}
|
||||||
|
|
||||||
|
_findNeedle(): WKAXNode | null {
|
||||||
|
if (this._payload.found)
|
||||||
|
return this;
|
||||||
|
for (const child of this._children) {
|
||||||
|
const found = child._findNeedle();
|
||||||
|
if (found)
|
||||||
|
return found;
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
children() {
|
isControl(): boolean {
|
||||||
return this._children;
|
switch (this._payload.role) {
|
||||||
|
case 'button':
|
||||||
|
case 'checkbox':
|
||||||
|
case 'ColorWell':
|
||||||
|
case 'combobox':
|
||||||
|
case 'DisclosureTriangle':
|
||||||
|
case 'listbox':
|
||||||
|
case 'menu':
|
||||||
|
case 'menubar':
|
||||||
|
case 'menuitem':
|
||||||
|
case 'menuitemcheckbox':
|
||||||
|
case 'menuitemradio':
|
||||||
|
case 'radio':
|
||||||
|
case 'scrollbar':
|
||||||
|
case 'searchbox':
|
||||||
|
case 'slider':
|
||||||
|
case 'spinbutton':
|
||||||
|
case 'switch':
|
||||||
|
case 'tab':
|
||||||
|
case 'textbox':
|
||||||
|
case 'TextField':
|
||||||
|
case 'tree':
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_findNeedle(): WKAXNode | null {
|
_isTextControl(): boolean {
|
||||||
if (this._payload.found)
|
switch (this._payload.role) {
|
||||||
return this;
|
case 'combobox':
|
||||||
for (const child of this._children) {
|
case 'searchfield':
|
||||||
const found = child._findNeedle();
|
case 'textbox':
|
||||||
if (found)
|
case 'TextField':
|
||||||
return found;
|
return true;
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
isControl(): boolean {
|
_name(): string {
|
||||||
switch (this._payload.role) {
|
if (this._payload.role === 'text')
|
||||||
case 'button':
|
return this._payload.value || '';
|
||||||
case 'checkbox':
|
return this._payload.name || '';
|
||||||
case 'ColorWell':
|
}
|
||||||
case 'combobox':
|
|
||||||
case 'DisclosureTriangle':
|
|
||||||
case 'listbox':
|
|
||||||
case 'menu':
|
|
||||||
case 'menubar':
|
|
||||||
case 'menuitem':
|
|
||||||
case 'menuitemcheckbox':
|
|
||||||
case 'menuitemradio':
|
|
||||||
case 'radio':
|
|
||||||
case 'scrollbar':
|
|
||||||
case 'searchbox':
|
|
||||||
case 'slider':
|
|
||||||
case 'spinbutton':
|
|
||||||
case 'switch':
|
|
||||||
case 'tab':
|
|
||||||
case 'textbox':
|
|
||||||
case 'TextField':
|
|
||||||
case 'tree':
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_isTextControl(): boolean {
|
isInteresting(insideControl: boolean): boolean {
|
||||||
switch (this._payload.role) {
|
const { role, focusable } = this._payload;
|
||||||
case 'combobox':
|
const name = this._name();
|
||||||
case 'searchfield':
|
if (role === 'ScrollArea')
|
||||||
case 'textbox':
|
|
||||||
case 'TextField':
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
if (role === 'WebArea')
|
||||||
|
return true;
|
||||||
|
|
||||||
_name(): string {
|
if (focusable || role === 'MenuListOption')
|
||||||
if (this._payload.role === 'text')
|
return true;
|
||||||
return this._payload.value || '';
|
|
||||||
return this._payload.name || '';
|
|
||||||
}
|
|
||||||
|
|
||||||
isInteresting(insideControl: boolean): boolean {
|
// If it's not focusable but has a control role, then it's interesting.
|
||||||
const { role, focusable } = this._payload;
|
if (this.isControl())
|
||||||
const name = this._name();
|
return true;
|
||||||
if (role === 'ScrollArea')
|
|
||||||
return false;
|
|
||||||
if (role === 'WebArea')
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (focusable || role === 'MenuListOption')
|
// A non focusable child of a control is not interesting
|
||||||
return true;
|
if (insideControl)
|
||||||
|
return false;
|
||||||
|
|
||||||
// If it's not focusable but has a control role, then it's interesting.
|
return this.isLeafNode() && !!name;
|
||||||
if (this.isControl())
|
}
|
||||||
return true;
|
|
||||||
|
|
||||||
// A non focusable child of a control is not interesting
|
_hasRendundantTextChild() {
|
||||||
if (insideControl)
|
if (this._children.length !== 1)
|
||||||
return false;
|
return false;
|
||||||
|
const child = this._children[0];
|
||||||
|
return child._payload.role === 'text' && this._payload.name === child._payload.value;
|
||||||
|
}
|
||||||
|
|
||||||
return this.isLeafNode() && !!name;
|
isLeafNode(): boolean {
|
||||||
}
|
if (!this._children.length)
|
||||||
|
return true;
|
||||||
_hasRendundantTextChild() {
|
|
||||||
if (this._children.length !== 1)
|
|
||||||
return false;
|
|
||||||
const child = this._children[0];
|
|
||||||
return child._payload.role === 'text' && this._payload.name === child._payload.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
isLeafNode(): boolean {
|
|
||||||
if (!this._children.length)
|
|
||||||
return true;
|
|
||||||
// WebKit on Linux ignores everything inside text controls, normalize this behavior
|
// WebKit on Linux ignores everything inside text controls, normalize this behavior
|
||||||
if (this._isTextControl())
|
if (this._isTextControl())
|
||||||
return true;
|
return true;
|
||||||
// WebKit for mac has text nodes inside heading, li, menuitem, a, and p nodes
|
// WebKit for mac has text nodes inside heading, li, menuitem, a, and p nodes
|
||||||
if (this._hasRendundantTextChild())
|
if (this._hasRendundantTextChild())
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
serialize(): types.SerializedAXNode {
|
||||||
|
const node: types.SerializedAXNode = {
|
||||||
|
role: WKRoleToARIARole.get(this._payload.role) || this._payload.role,
|
||||||
|
name: this._name(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if ('description' in this._payload && this._payload.description !== node.name)
|
||||||
|
node.description = this._payload.description;
|
||||||
|
|
||||||
|
if ('roledescription' in this._payload) {
|
||||||
|
const roledescription = this._payload.roledescription;
|
||||||
|
if (roledescription !== this._payload.role && WKUnhelpfulRoleDescriptions.get(this._payload.role) !== roledescription)
|
||||||
|
node.roledescription = roledescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
serialize(): types.SerializedAXNode {
|
if ('value' in this._payload && this._payload.role !== 'text') {
|
||||||
const node: types.SerializedAXNode = {
|
if (typeof this._payload.value === 'string')
|
||||||
role: WKRoleToARIARole.get(this._payload.role) || this._payload.role,
|
node.valueString = this._payload.value;
|
||||||
name: this._name(),
|
else if (typeof this._payload.value === 'number')
|
||||||
};
|
node.valueNumber = this._payload.value;
|
||||||
|
|
||||||
if ('description' in this._payload && this._payload.description !== node.name)
|
|
||||||
node.description = this._payload.description;
|
|
||||||
|
|
||||||
if ('roledescription' in this._payload) {
|
|
||||||
const roledescription = this._payload.roledescription;
|
|
||||||
if (roledescription !== this._payload.role && WKUnhelpfulRoleDescriptions.get(this._payload.role) !== roledescription)
|
|
||||||
node.roledescription = roledescription;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('value' in this._payload && this._payload.role !== 'text') {
|
|
||||||
if (typeof this._payload.value === 'string')
|
|
||||||
node.valueString = this._payload.value;
|
|
||||||
else if (typeof this._payload.value === 'number')
|
|
||||||
node.valueNumber = this._payload.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('checked' in this._payload)
|
|
||||||
node.checked = this._payload.checked === 'true' ? 'checked' : this._payload.checked === 'false' ? 'unchecked' : 'mixed';
|
|
||||||
|
|
||||||
if ('pressed' in this._payload)
|
|
||||||
node.pressed = this._payload.pressed === 'true' ? 'pressed' : this._payload.pressed === 'false' ? 'released' : 'mixed';
|
|
||||||
|
|
||||||
const userStringProperties: Array<keyof types.SerializedAXNode & keyof Protocol.Page.AXNode> = [
|
|
||||||
'keyshortcuts',
|
|
||||||
'valuetext'
|
|
||||||
];
|
|
||||||
for (const userStringProperty of userStringProperties) {
|
|
||||||
if (!(userStringProperty in this._payload))
|
|
||||||
continue;
|
|
||||||
(node as any)[userStringProperty] = this._payload[userStringProperty];
|
|
||||||
}
|
|
||||||
|
|
||||||
const booleanProperties: Array<keyof types.SerializedAXNode & keyof Protocol.Page.AXNode> = [
|
|
||||||
'disabled',
|
|
||||||
'expanded',
|
|
||||||
'focused',
|
|
||||||
'modal',
|
|
||||||
'multiline',
|
|
||||||
'multiselectable',
|
|
||||||
'readonly',
|
|
||||||
'required',
|
|
||||||
'selected',
|
|
||||||
];
|
|
||||||
for (const booleanProperty of booleanProperties) {
|
|
||||||
// WebArea and ScorllArea treat focus differently than other nodes. They report whether their frame has focus,
|
|
||||||
// not whether focus is specifically on the root node.
|
|
||||||
if (booleanProperty === 'focused' && (this._payload.role === 'WebArea' || this._payload.role === 'ScrollArea'))
|
|
||||||
continue;
|
|
||||||
const value = this._payload[booleanProperty];
|
|
||||||
if (!value)
|
|
||||||
continue;
|
|
||||||
(node as any)[booleanProperty] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
const numericalProperties: Array<keyof types.SerializedAXNode & keyof Protocol.Page.AXNode> = [
|
|
||||||
'level',
|
|
||||||
'valuemax',
|
|
||||||
'valuemin',
|
|
||||||
];
|
|
||||||
for (const numericalProperty of numericalProperties) {
|
|
||||||
if (!(numericalProperty in this._payload))
|
|
||||||
continue;
|
|
||||||
(node as any)[numericalProperty] = (this._payload as any)[numericalProperty];
|
|
||||||
}
|
|
||||||
const tokenProperties: Array<keyof types.SerializedAXNode & keyof Protocol.Page.AXNode> = [
|
|
||||||
'autocomplete',
|
|
||||||
'haspopup',
|
|
||||||
'invalid',
|
|
||||||
];
|
|
||||||
for (const tokenProperty of tokenProperties) {
|
|
||||||
const value = (this._payload as any)[tokenProperty];
|
|
||||||
if (!value || value === 'false')
|
|
||||||
continue;
|
|
||||||
(node as any)[tokenProperty] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
const orientationIsApplicable = new Set([
|
|
||||||
'ScrollArea',
|
|
||||||
'scrollbar',
|
|
||||||
'listbox',
|
|
||||||
'combobox',
|
|
||||||
'menu',
|
|
||||||
'tree',
|
|
||||||
'separator',
|
|
||||||
'slider',
|
|
||||||
'tablist',
|
|
||||||
'toolbar',
|
|
||||||
]);
|
|
||||||
if (this._payload.orientation && orientationIsApplicable.has(this._payload.role))
|
|
||||||
node.orientation = this._payload.orientation;
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ('checked' in this._payload)
|
||||||
|
node.checked = this._payload.checked === 'true' ? 'checked' : this._payload.checked === 'false' ? 'unchecked' : 'mixed';
|
||||||
|
|
||||||
|
if ('pressed' in this._payload)
|
||||||
|
node.pressed = this._payload.pressed === 'true' ? 'pressed' : this._payload.pressed === 'false' ? 'released' : 'mixed';
|
||||||
|
|
||||||
|
const userStringProperties: Array<keyof types.SerializedAXNode & keyof Protocol.Page.AXNode> = [
|
||||||
|
'keyshortcuts',
|
||||||
|
'valuetext'
|
||||||
|
];
|
||||||
|
for (const userStringProperty of userStringProperties) {
|
||||||
|
if (!(userStringProperty in this._payload))
|
||||||
|
continue;
|
||||||
|
(node as any)[userStringProperty] = this._payload[userStringProperty];
|
||||||
|
}
|
||||||
|
|
||||||
|
const booleanProperties: Array<keyof types.SerializedAXNode & keyof Protocol.Page.AXNode> = [
|
||||||
|
'disabled',
|
||||||
|
'expanded',
|
||||||
|
'focused',
|
||||||
|
'modal',
|
||||||
|
'multiline',
|
||||||
|
'multiselectable',
|
||||||
|
'readonly',
|
||||||
|
'required',
|
||||||
|
'selected',
|
||||||
|
];
|
||||||
|
for (const booleanProperty of booleanProperties) {
|
||||||
|
// WebArea and ScorllArea treat focus differently than other nodes. They report whether their frame has focus,
|
||||||
|
// not whether focus is specifically on the root node.
|
||||||
|
if (booleanProperty === 'focused' && (this._payload.role === 'WebArea' || this._payload.role === 'ScrollArea'))
|
||||||
|
continue;
|
||||||
|
const value = this._payload[booleanProperty];
|
||||||
|
if (!value)
|
||||||
|
continue;
|
||||||
|
(node as any)[booleanProperty] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const numericalProperties: Array<keyof types.SerializedAXNode & keyof Protocol.Page.AXNode> = [
|
||||||
|
'level',
|
||||||
|
'valuemax',
|
||||||
|
'valuemin',
|
||||||
|
];
|
||||||
|
for (const numericalProperty of numericalProperties) {
|
||||||
|
if (!(numericalProperty in this._payload))
|
||||||
|
continue;
|
||||||
|
(node as any)[numericalProperty] = (this._payload as any)[numericalProperty];
|
||||||
|
}
|
||||||
|
const tokenProperties: Array<keyof types.SerializedAXNode & keyof Protocol.Page.AXNode> = [
|
||||||
|
'autocomplete',
|
||||||
|
'haspopup',
|
||||||
|
'invalid',
|
||||||
|
];
|
||||||
|
for (const tokenProperty of tokenProperties) {
|
||||||
|
const value = (this._payload as any)[tokenProperty];
|
||||||
|
if (!value || value === 'false')
|
||||||
|
continue;
|
||||||
|
(node as any)[tokenProperty] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const orientationIsApplicable = new Set([
|
||||||
|
'ScrollArea',
|
||||||
|
'scrollbar',
|
||||||
|
'listbox',
|
||||||
|
'combobox',
|
||||||
|
'menu',
|
||||||
|
'tree',
|
||||||
|
'separator',
|
||||||
|
'slider',
|
||||||
|
'tablist',
|
||||||
|
'toolbar',
|
||||||
|
]);
|
||||||
|
if (this._payload.orientation && orientationIsApplicable.has(this._payload.role))
|
||||||
|
node.orientation = this._payload.orientation;
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue