diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 78f211df9..e7af5a6a4 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -472,6 +472,8 @@ jobs:
working-directory: report-react
- run: npm install
working-directory: accessibility-checker-extension
+ - run: npm install
+ working-directory: accessibility-checker-extension/test
- run: npm install
working-directory: rule-server
- run: npm run build
@@ -484,6 +486,9 @@ jobs:
working-directory: accessibility-checker-extension
- run: npm run package:browser
working-directory: accessibility-checker-extension
+ - name: UI Tests
+ run: npm test
+ working-directory: accessibility-checker-extension/test
- name: Upload packed extension
uses: actions/upload-artifact@v1
with:
@@ -498,9 +503,6 @@ jobs:
with:
name: accessibility-checker-extension for Firefox
path: accessibility-checker-extension/package/accessibility-checker-extension.zip
- - name: Jest tests
- run: npm test
- working-directory: accessibility-checker-extension
rule-deploy:
runs-on: ubuntu-22.04
diff --git a/accessibility-checker-extension/package.json b/accessibility-checker-extension/package.json
index bb36d31df..8dc53e7f4 100644
--- a/accessibility-checker-extension/package.json
+++ b/accessibility-checker-extension/package.json
@@ -12,8 +12,7 @@
"build:watch:local": "node preprocess && npm run build:report && cross-env NODE_ENV=watch_local SASS_PATH=node_modules:src:node_modules/carbon-components/scss/globals/scss/vendor webpack --mode production",
"clean": "shx rm -rf ./dist && shx rm -rf ./package",
"clean:all": "shx rm -rf ./dist && shx rm -rf ./coverage && shx rm -rf ./package && shx rm -rf ./node_modules",
- "test": "jest",
- "test:coverage": "jest --collect-coverage",
+ "test": "cd test && npm test",
"package:browser": "npm run build:prod && shx mkdir -p package && cd dist && zip -Zd -r ../package/accessibility-checker-extension.zip ."
},
"license": "Apache-2.0",
@@ -33,10 +32,8 @@
"webext-redux": "^2.1.9"
},
"devDependencies": {
- "@jest/globals": "^29.7.0",
"@svgr/webpack": "^6.1.2",
"@types/chrome": "^0.0.171",
- "@types/jest": "^29.5.1",
"@types/markdown-to-jsx": "^7.0.0",
"@types/node": "^18.15.3",
"@types/react": "17.0.37",
@@ -51,8 +48,6 @@
"css-loader": "^6.5.1",
"html-webpack-plugin": "^5.5.0",
"identity-obj-proxy": "^3.0.0",
- "jest": "^29.7.0",
- "jest-environment-jsdom": "^29.7.0",
"mini-css-extract-plugin": "^2.4.5",
"react-test-renderer": "^17.0.2",
"resize-observer-polyfill": "^1.5.1",
@@ -61,7 +56,6 @@
"shx": "^0.3.3",
"style-loader": "^3.3.1",
"terser-webpack-plugin": "^5.3.7",
- "ts-jest": "^29.1.0",
"ts-loader": "^9.2.6",
"tslint": "^5.20.1",
"typescript": "^4.5.4",
diff --git a/accessibility-checker-extension/src/html/devtoolsElements.html b/accessibility-checker-extension/src/html/devtoolsElements.html
index 4e8d3714c..bdfa48a9a 100644
--- a/accessibility-checker-extension/src/html/devtoolsElements.html
+++ b/accessibility-checker-extension/src/html/devtoolsElements.html
@@ -1,5 +1,5 @@
-
+
IBM Accessibility Checker Extension: Assessment
diff --git a/accessibility-checker-extension/src/html/devtoolsMain.html b/accessibility-checker-extension/src/html/devtoolsMain.html
index 34b3d897b..b6afd235b 100644
--- a/accessibility-checker-extension/src/html/devtoolsMain.html
+++ b/accessibility-checker-extension/src/html/devtoolsMain.html
@@ -1,5 +1,5 @@
-
+
IBM Accessibility Checker Extension: Checker
diff --git a/accessibility-checker-extension/src/ts/background/backgroundController.ts b/accessibility-checker-extension/src/ts/background/backgroundController.ts
index 8225804a6..f1b0acfb4 100644
--- a/accessibility-checker-extension/src/ts/background/backgroundController.ts
+++ b/accessibility-checker-extension/src/ts/background/backgroundController.ts
@@ -116,7 +116,7 @@ class BackgroundController extends Controller {
this.addEventListener(listener, `BG_onTabUpdate`);
}
- public async getTabInfo(tabId?: number) : Promise {
+ public async getTabInfo(tabId: number) : Promise {
return this.hook("getTabInfo", tabId, async () => {
let tab = await new Promise(async (resolve2) => {
let manifest = chrome.runtime.getManifest();
@@ -317,12 +317,12 @@ class BackgroundController extends Controller {
/**
* Get the rulesets for the currently loaded engine
*/
- public async getRulesets(senderTabId: number) : Promise {
- return this.hook("getRulesets", senderTabId, async () => {
- await this.initTab(senderTabId!);
+ public async getRulesets(contentTabId: number) : Promise {
+ return this.hook("getRulesets", contentTabId, async () => {
+ await this.initTab(contentTabId!);
// let isLoaded = await this.isEngineLoaded(senderTabId);
// isLoaded && console.log("Engine loaded", senderTabId) || console.log("Engine not loaded", senderTabId);
- return await myExecuteScript2(senderTabId, () => {
+ return await myExecuteScript2(contentTabId, () => {
let checker = new (window).aceIBMa.Checker();
return checker.rulesets;
});
@@ -336,15 +336,16 @@ class BackgroundController extends Controller {
}
///// Scan related functions /////////////////////////////////////////
- public async requestScan(senderTabId: number) {
- return this.hook("requestScan", senderTabId, async () => {
- getDevtoolsController(false, "remote", senderTabId).setScanningState("initializing");
- await this.initTab(senderTabId!);
+ public async requestScan(tabIds: {toolTabId: number, contentTabId: number}) {
+ return this.hook("requestScan", tabIds, async () => {
+ const { toolTabId, contentTabId } = tabIds;
+ getDevtoolsController(toolTabId, false, "remote").setScanningState("initializing");
+ await this.initTab(contentTabId!);
// We want this to execute after the message returns
(async () => {
let settings = await this.getSettings();
- getDevtoolsController(false, "remote", senderTabId).setScanningState("running");
- let report : IReport = await myExecuteScript2(senderTabId, (settings: ISettings) => {
+ getDevtoolsController(toolTabId, false, "remote").setScanningState("running");
+ let report : IReport = await myExecuteScript2(contentTabId, (settings: ISettings) => {
let checker = new (window).aceIBMa.Checker();
if (Object.keys(checker.engine.nlsMap).length === 0) {
// Some problem grabbing messages for given locale. Let's try to get en-US data out of the engine
@@ -415,7 +416,7 @@ class BackgroundController extends Controller {
let browser = (navigator.userAgent.match(/\) ([^)]*)$/) || ["", "Unknown"])[1];
this.metrics.profileV2(report.totalTime, browser, settings.selected_ruleset.id);
this.metrics.sendLogsV2();
- getDevtoolsController(false, "remote", senderTabId).setScanningState("processing");
+ getDevtoolsController(toolTabId, false, "remote").setScanningState("processing");
if (report) {
for (const result of report.results) {
if (result.ruleTime > 50) {
@@ -459,8 +460,8 @@ class BackgroundController extends Controller {
report.counts = counts;
}
- getDevtoolsController(false, "remote", senderTabId).setReport(report);
- getDevtoolsController(false, "remote", senderTabId).setScanningState("idle");
+ getDevtoolsController(toolTabId, false, "remote").setReport(report);
+ getDevtoolsController(toolTabId, false, "remote").setScanningState("idle");
})();
return {};
});
diff --git a/accessibility-checker-extension/src/ts/contentScripts/TabStopHighlight.ts b/accessibility-checker-extension/src/ts/contentScripts/TabStopHighlight.ts
index f37cd0ddc..d573b5762 100644
--- a/accessibility-checker-extension/src/ts/contentScripts/TabStopHighlight.ts
+++ b/accessibility-checker-extension/src/ts/contentScripts/TabStopHighlight.ts
@@ -229,7 +229,7 @@ export default class TabStopHighlight {
let issue = this.getIssueByXpath(elementXpath,regularTabstops);
if (issue) {
let tabId = await getBGController().getTabId();
- let devtoolsController = getDevtoolsController(true, "remote", tabId);
+ let devtoolsController = getDevtoolsController(tabId, true, "remote");
await devtoolsController.setSelectedIssue(null);
if (await devtoolsController.getActivePanel() === "elements") {
await devtoolsController.inspectPath(elementXpath,element);
@@ -247,7 +247,7 @@ export default class TabStopHighlight {
let issue = this.getIssueByXpath(elementXpath,tabStopsErrors);
if (issue) {
let tabId = await getBGController().getTabId();
- let devtoolsController = getDevtoolsController(true, "remote", tabId);
+ let devtoolsController = getDevtoolsController(tabId, true, "remote");
await devtoolsController.setSelectedIssue(issue);
if (await devtoolsController.getActivePanel() === "elements") {
await devtoolsController.inspectPath(elementXpath,element);
diff --git a/accessibility-checker-extension/src/ts/contentScripts/viewInspect.ts b/accessibility-checker-extension/src/ts/contentScripts/viewInspect.ts
index 02ebc242a..2574a6b6e 100644
--- a/accessibility-checker-extension/src/ts/contentScripts/viewInspect.ts
+++ b/accessibility-checker-extension/src/ts/contentScripts/viewInspect.ts
@@ -24,7 +24,7 @@ type Overlays = { elem: HTMLDivElement, info: HTMLDivElement };
(async () => {
let myTabId = await getBGController().getTabId()!;
- let devtoolsController = getDevtoolsController(true, "remote", myTabId);
+ let devtoolsController = getDevtoolsController(myTabId, true);
function setProps(objToModify: T, objPropsToSet: Partial) {
for (const key in objPropsToSet) {
diff --git a/accessibility-checker-extension/src/ts/contentScripts/viewKCM.ts b/accessibility-checker-extension/src/ts/contentScripts/viewKCM.ts
index 60c611329..5a1319508 100644
--- a/accessibility-checker-extension/src/ts/contentScripts/viewKCM.ts
+++ b/accessibility-checker-extension/src/ts/contentScripts/viewKCM.ts
@@ -28,7 +28,7 @@ let myKCMState = false;
(async() => {
let settings = await bgController.getSettings();
let myTabId = await bgController.getTabId()!;
- let devtoolsController = getDevtoolsController(true, "remote", myTabId);
+ let devtoolsController = getDevtoolsController(myTabId, true);
async function refreshDrawing() {
// if viewState.kcm === true then scan has occurred and KCM button has been pushed
@@ -305,7 +305,7 @@ function deleteDrawing(classToRemove: string) {
document.documentElement.addEventListener("keypress", async (evt: KeyboardEvent) => {
if (evt.code === "KeyS" && evt.ctrlKey && evt.altKey) {
let tabId = await bgController.getTabId();
- bgController.requestScan(tabId);
+ bgController.requestScan({ toolTabId: tabId, contentTabId: tabId });
evt.preventDefault();
evt.stopPropagation();
}
diff --git a/accessibility-checker-extension/src/ts/devtools/components/helpScreen.tsx b/accessibility-checker-extension/src/ts/devtools/components/helpScreen.tsx
index 4ff7d522f..885b72f3f 100644
--- a/accessibility-checker-extension/src/ts/devtools/components/helpScreen.tsx
+++ b/accessibility-checker-extension/src/ts/devtools/components/helpScreen.tsx
@@ -19,6 +19,7 @@ import { Column, InlineLoading, Grid } from "@carbon/react";
import { IIssue } from "../../interfaces/interfaces";
import { getDevtoolsController } from "../devtoolsController";
import { getBGController } from "../../background/backgroundController";
+import { getDevtoolsAppController } from "../devtoolsAppController";
interface IHelpScreenState {
issue: IIssue | null
@@ -38,13 +39,14 @@ export default class HelpScreen extends React.Component {
- HelpScreen.devtoolsController.addSelectedIssueListener(async (issue) => {
+ this.devtoolsController.addSelectedIssueListener(async (issue) => {
this.setIssue(issue);
});
- let issue = await HelpScreen.devtoolsController.getSelectedIssue();
+ let issue = await this.devtoolsController.getSelectedIssue();
this.setIssue(issue!);
}
diff --git a/accessibility-checker-extension/src/ts/devtools/components/reportSection.tsx b/accessibility-checker-extension/src/ts/devtools/components/reportSection.tsx
index d2e88a4c7..8731d89d3 100644
--- a/accessibility-checker-extension/src/ts/devtools/components/reportSection.tsx
+++ b/accessibility-checker-extension/src/ts/devtools/components/reportSection.tsx
@@ -40,9 +40,6 @@ import { getDevtoolsAppController } from '../devtoolsAppController';
import { ReportTabs } from './reports/reportTabs';
import { UtilKCM } from '../../util/UtilKCM';
import { getBGController, issueBaselineMatch } from '../../background/backgroundController';
-import { getTabId } from '../../util/tabId';
-
-let devtoolsController = getDevtoolsController();
interface ReportSectionProps {
panel: ePanel;
@@ -60,10 +57,11 @@ interface ReportSectionState {
ignoredIssues: UIIssue[]
}
-let bgController = getBGController();
-let appController = getDevtoolsAppController();
-
export class ReportSection extends React.Component {
+ private bgController = getBGController();
+ private devtoolsAppController = getDevtoolsAppController();
+ private devtoolsController = getDevtoolsController(this.devtoolsAppController.toolTabId);
+
state: ReportSectionState = {
report: null,
selectedPath: null,
@@ -76,42 +74,42 @@ export class ReportSection extends React.Component {
- devtoolsController.addReportListener(this.reportListener);
- let report = await devtoolsController.getReport();
+ this.devtoolsController.addReportListener(this.reportListener);
+ let report = await this.devtoolsController.getReport();
this.setState({
- canScan: (await bgController.getTabInfo(getTabId()!)).canScan
+ canScan: (await this.bgController.getTabInfo(this.devtoolsAppController.contentTabId)).canScan
});
this.reportListener(report!);
- devtoolsController.addSelectedElementPathListener(this.selectedElementListener);
- let path = await devtoolsController.getSelectedElementPath();
+ this.devtoolsController.addSelectedElementPathListener(this.selectedElementListener);
+ let path = await this.devtoolsController.getSelectedElementPath();
this.setPath(path!);
- devtoolsController.addFocusModeListener(async (newValue: boolean) => {
+ this.devtoolsController.addFocusModeListener(async (newValue: boolean) => {
this.setState({ focusMode: newValue });
})
- devtoolsController.addViewStateListener(async (viewState: ViewState) => {
+ this.devtoolsController.addViewStateListener(async (viewState: ViewState) => {
this.setState({ viewState });
})
this.setState({
- focusMode: await devtoolsController.getFocusMode(),
- viewState: (await devtoolsController.getViewState())!
+ focusMode: await this.devtoolsController.getFocusMode(),
+ viewState: (await this.devtoolsController.getViewState())!
})
- bgController.addIgnoreUpdateListener(async ({ url, issues }) => {
- if (url === (await bgController.getTabInfo(getTabId())).url) {
+ this.bgController.addIgnoreUpdateListener(async ({ url, issues }) => {
+ if (url === (await this.bgController.getTabInfo(this.devtoolsAppController.contentTabId!)).url) {
this.setState({ ignoredIssues: issues });
}
})
- appController.addLevelFilterListener(() => {
+ this.devtoolsAppController.addLevelFilterListener(() => {
this.setState({});
})
}
componentWillUnmount(): void {
- devtoolsController.removeReportListener(this.reportListener);
+ this.devtoolsController.removeReportListener(this.reportListener);
}
onResetFilters() {
- appController.setLevelFilters({
+ this.devtoolsAppController.setLevelFilters({
"Violation": true,
"Needs review": true,
"Recommendation": true,
@@ -123,12 +121,12 @@ export class ReportSection extends React.Component issue.value[1] !== "PASS" || issue.ruleId === "detector_tabbable");
}
- let url = (await bgController.getTabInfo(getTabId())).url!;
- let alreadyIgnored = await bgController.getIgnore(url);
+ let url = (await this.bgController.getTabInfo(this.devtoolsAppController.contentTabId!)).url!;
+ let alreadyIgnored = await this.bgController.getIgnore(url);
this.setState({
ignoredIssues: alreadyIgnored,
report,
- canScan: (await bgController.getTabInfo(getTabId()!)).canScan
+ canScan: (await this.bgController.getTabInfo(this.devtoolsAppController.contentTabId!)).canScan
});
}
@@ -188,7 +186,7 @@ export class ReportSection extends React.Component {
issue.ignored = this.state.ignoredIssues.some(ignoredIssue => issueBaselineMatch(ignoredIssue, issue));
- const checked = appController.getLevelFilters();
+ const checked = this.devtoolsAppController.getLevelFilters();
let retVal = ( ((checked["Hidden"] && issue.ignored) || checked[UtilIssue.valueToStringSingular(issue.value) as eFilterLevel])
&& (!this.state.focusMode
|| !this.state.selectedPath
@@ -213,8 +211,8 @@ export class ReportSection extends React.Component = [];
- for (const key of appController.getLevelFilterKeys()) {
- if (appController.getLevelFilter(key)) {
+ for (const key of this.devtoolsAppController.getLevelFilterKeys()) {
+ if (this.devtoolsAppController.getLevelFilter(key)) {
levelSelectedItems.push(filterItems.find(filtItem => filtItem.text === UtilIssue.singToStringPlural(key))!)
}
}
@@ -275,14 +273,14 @@ export class ReportSection extends React.Component {
- let checked = appController.getLevelFilters();
+ let checked = this.devtoolsAppController.getLevelFilters();
if (evt.selectedItems != undefined) {
checked["Violation"] = evt.selectedItems.some((item: any) => item.text === "Violations");
checked["Needs review"] = evt.selectedItems.some((item: any) => item.text === "Needs review");
checked["Recommendation"] = evt.selectedItems.some((item: any) => item.text === "Recommendations");
checked["Hidden"] = evt.selectedItems.some((item: any) => item.text === "Hidden");
}
- appController.setLevelFilters(checked);
+ this.devtoolsAppController.setLevelFilters(checked);
}}
/>
}
@@ -293,7 +291,7 @@ export class ReportSection extends React.Component devtoolsController.exportXLS("last") }
+ onClick={() => this.devtoolsController.exportXLS("last") }
>Export XLS
@@ -314,7 +312,7 @@ export class ReportSection extends React.Component {
- getDevtoolsAppController().setSecondaryView("kcm_overview");
- getDevtoolsAppController().openSecondary("#kcmInfo");
+ this.devtoolsAppController.setSecondaryView("kcm_overview");
+ this.devtoolsAppController.openSecondary("#kcmInfo");
}).bind(this)}>
@@ -386,7 +384,7 @@ export class ReportSection extends React.Component extends React.Component, ReportTreeGridState> {
- private static devtoolsAppController = getDevtoolsAppController();
- private static devtoolsController = getDevtoolsController();
- private static bgcontroller = getBGController();
+ private devtoolsAppController = getDevtoolsAppController();
+ private devtoolsController = getDevtoolsController(this.devtoolsAppController.toolTabId);
+ private bgcontroller = getBGController();
private treeGridRef = React.createRef();
state: ReportTreeGridState = {
expandedGroups: [],
@@ -100,7 +99,7 @@ export class ReportTreeGrid extends React.Component {
- ReportTreeGrid.devtoolsController.addSelectedIssueListener(async (issue) => {
+ this.devtoolsController.addSelectedIssueListener(async (issue) => {
for (const group of this.props.rowData!) {
for (const groupIssue of group.children) {
if (groupIssue.path.dom === issue.path.dom
@@ -112,17 +111,17 @@ export class ReportTreeGrid extends React.Component 0) {
this.setState({ expandedGroups: this.props.rowData?.map(group => group.id), tabRowId: "tableGridHeader" });
}
- ReportTreeGrid.devtoolsController.addViewStateListener(async (viewState: ViewState) => {
+ this.devtoolsController.addViewStateListener(async (viewState: ViewState) => {
this.setState({ viewState });
})
this.setState({
- viewState: (await ReportTreeGrid.devtoolsController.getViewState())!
+ viewState: (await this.devtoolsController.getViewState())!
})
}
@@ -222,19 +221,19 @@ export class ReportTreeGrid extends React.Component extends React.Component value.id === focusedElemId);
@@ -575,7 +574,7 @@ export class ReportTreeGrid extends React.Component {
- getDevtoolsController().setFocusMode(false);
+ this.devtoolsController.setFocusMode(false);
}}
>turn off focus view, extends React.Component {
+ onClick={(evt: any) => {
this.onRow(group, thisIssue);
- ReportTreeGrid.devtoolsAppController.setSecondaryView("help");
- ReportTreeGrid.devtoolsAppController.openSecondary(`#${rowId} a`);
+ this.devtoolsAppController.setSecondaryView("help");
+ this.devtoolsAppController.openSecondary(`#${rowId} a`);
+ evt.preventDefault();
}}
// onKeyDown={(evt: React.KeyboardEvent) => {
// if (evt.key === "Enter" || evt.key === "Return") {
// this.onRow(group, thisIssue);
- // ReportTreeGrid.devtoolsAppController.openSecondary(`#${rowId} a`);
+ // this.devtoolsAppController.openSecondary(`#${rowId} a`);
// }
// }}
>Learn more
@@ -870,11 +870,11 @@ export class ReportTreeGrid extends React.Component {
- let url = (await ReportTreeGrid.bgcontroller.getTabInfo(getTabId())).url!;
- ReportTreeGrid.bgcontroller.setIgnore(url, this.state.checkedIssues, ignoreAction !== "Show");
+ let url = (await this.bgcontroller.getTabInfo(this.devtoolsAppController.contentTabId!)).url!;
+ this.bgcontroller.setIgnore(url, this.state.checkedIssues, ignoreAction !== "Show");
this.setState({checkedIssues: []});
- let report = await ReportTreeGrid.devtoolsController.getReport();
- await ReportTreeGrid.devtoolsController.setReport(report);
+ let report = await this.devtoolsController.getReport();
+ await this.devtoolsController.setReport(report);
this.props.onFilterToolbar(true);
}}
>{ignoreAction}
diff --git a/accessibility-checker-extension/src/ts/devtools/components/reports/reportReqts.tsx b/accessibility-checker-extension/src/ts/devtools/components/reports/reportReqts.tsx
index 93f2c4257..7324f21af 100644
--- a/accessibility-checker-extension/src/ts/devtools/components/reports/reportReqts.tsx
+++ b/accessibility-checker-extension/src/ts/devtools/components/reports/reportReqts.tsx
@@ -21,8 +21,8 @@ import { UtilIssue } from '../../../util/UtilIssue';
import "../reportSection.scss";
import { getBGController } from '../../../background/backgroundController';
-import { getTabId } from '../../../util/tabId';
import { ePanel } from '../../devtoolsController';
+import { getDevtoolsAppController } from '../../devtoolsAppController';
interface ReportProps {
unfilteredCount: number
@@ -49,8 +49,9 @@ export class ReportReqts extends React.Component {
async componentDidMount(): Promise {
let bgController = getBGController();
+ let appController = getDevtoolsAppController();
let settings = await bgController.getSettings();
- let rulesets = await bgController.getRulesets(getTabId()!);
+ let rulesets = await bgController.getRulesets(appController.contentTabId!);
let ruleset = rulesets.find(policy => policy.id === settings.selected_ruleset.id);
if (ruleset) {
this.setState({ ruleset });
diff --git a/accessibility-checker-extension/src/ts/devtools/components/scanSection.tsx b/accessibility-checker-extension/src/ts/devtools/components/scanSection.tsx
index 95c87cd2f..476253b95 100644
--- a/accessibility-checker-extension/src/ts/devtools/components/scanSection.tsx
+++ b/accessibility-checker-extension/src/ts/devtools/components/scanSection.tsx
@@ -20,7 +20,6 @@ import { IIssue, IReport, UIIssue, eFilterLevel } from '../../interfaces/interfa
import { UtilIssue } from '../../util/UtilIssue';
import { UtilIssueReact } from '../../util/UtilIssueReact';
import { getDevtoolsController, ScanningState, ViewState } from '../devtoolsController';
-import { getTabId } from '../../util/tabId';
import { getBGController, issueBaselineMatch, TabChangeType } from '../../background/backgroundController';
import {
Button,
@@ -45,9 +44,7 @@ import "./scanSection.scss";
import { getDevtoolsAppController } from '../devtoolsAppController';
import { DefinitionTooltip } from '@carbon/react';
import { BrowserDetection } from "../../util/browserDetection";
-
-let devtoolsController = getDevtoolsController();
-let bgController = getBGController();
+import { getTabIdAsync } from '../../util/tabId';
interface ScanSectionState {
report: IReport | null,
@@ -98,6 +95,10 @@ type CountType = {
}
export class ScanSection extends React.Component<{}, ScanSectionState> {
+ private devtoolsAppController = getDevtoolsAppController();
+ private devtoolsController = getDevtoolsController(this.devtoolsAppController.toolTabId);
+ private bgController = getBGController();
+
state : ScanSectionState = {
report: null,
selectedPath: null,
@@ -132,8 +133,8 @@ export class ScanSection extends React.Component<{}, ScanSectionState> {
hasReportContent = true;
}
// If a scan never started, we can't be done
- let url = (await bgController.getTabInfo(getTabId())).url!;
- let alreadyIgnored = await bgController.getIgnore(url);
+ let url = (await this.bgController.getTabInfo(getDevtoolsAppController().contentTabId)).url!;
+ let alreadyIgnored = await this.bgController.getIgnore(url);
self.setState( {
ignoredIssues: alreadyIgnored,
scanningState: this.state.scanningState !== "idle"? "done" : "idle",
@@ -154,63 +155,64 @@ export class ScanSection extends React.Component<{}, ScanSectionState> {
async componentDidMount(): Promise {
- devtoolsController.addReportListener(this.reportListener);
- devtoolsController.addScanningStateListener(async (newState) => {
+ let tabId = getDevtoolsAppController().contentTabId
+ this.devtoolsController.addReportListener(this.reportListener);
+ this.devtoolsController.addScanningStateListener(async (newState) => {
this.setState({scanningState: newState });
});
- devtoolsController.addViewStateListener(async (newState) => {
+ this.devtoolsController.addViewStateListener(async (newState) => {
this.setState( { viewState: newState });
})
- devtoolsController.addStoreReportsListener(async (newState) => {
+ this.devtoolsController.addStoreReportsListener(async (newState) => {
this.setState( {
storeReports: newState,
- storedReportsCount: (await devtoolsController.getStoredReportsMeta()).length
+ storedReportsCount: (await this.devtoolsController.getStoredReportsMeta()).length
});
})
- devtoolsController.addStoredReportsMetaListener(async (newState) => {
+ this.devtoolsController.addStoredReportsMetaListener(async (newState) => {
this.setState( {
storedReportsCount: newState.length
});
})
- devtoolsController.addSelectedElementPathListener(async (newPath) => {
+ this.devtoolsController.addSelectedElementPathListener(async (newPath) => {
this.setState( { selectedElemPath: newPath });
})
- devtoolsController.addFocusModeListener(async (newValue) => {
+ this.devtoolsController.addFocusModeListener(async (newValue) => {
this.setState({ focusMode: newValue })
})
- bgController.addTabChangeListener(async (content: TabChangeType) => {
+ this.bgController.addTabChangeListener(async (content: TabChangeType) => {
if (content.changeInfo.status) {
this.setState({ pageStatus: content.changeInfo.status, scannedOnce: false });
}
if (content.changeInfo.status === "complete") {
this.setState({
- canScan: (await bgController.getTabInfo(getTabId()!)).canScan
+ canScan: (await this.bgController.getTabInfo(tabId)).canScan
});
}
});
- bgController.addIgnoreUpdateListener(async ({ url, issues }) => {
- if (url === (await bgController.getTabInfo(getTabId())).url) {
+ this.bgController.addIgnoreUpdateListener(async ({ url, issues }) => {
+ if (url === (await this.bgController.getTabInfo(tabId)).url) {
this.setState({ ignoredIssues: issues });
}
})
- this.reportListener((await devtoolsController.getReport())!);
+ this.reportListener((await this.devtoolsController.getReport())!);
this.setState({
- viewState: (await devtoolsController.getViewState())!,
- storeReports: (await devtoolsController.getStoreReports()),
- selectedElemPath: (await devtoolsController.getSelectedElementPath())! || "/html",
- focusMode: (await devtoolsController.getFocusMode()),
- storedReportsCount: (await devtoolsController.getStoredReportsMeta()).length,
- canScan: (await bgController.getTabInfo(getTabId()!)).canScan
+ viewState: (await this.devtoolsController.getViewState())!,
+ storeReports: (await this.devtoolsController.getStoreReports()),
+ selectedElemPath: (await this.devtoolsController.getSelectedElementPath())! || "/html",
+ focusMode: (await this.devtoolsController.getFocusMode()),
+ storedReportsCount: (await this.devtoolsController.getStoredReportsMeta()).length,
+ canScan: (await this.bgController.getTabInfo(tabId)).canScan
});
}
componentWillUnmount(): void {
- devtoolsController.removeReportListener(this.reportListener);
+ this.devtoolsController.removeReportListener(this.reportListener);
}
async scan() {
this.setState( { scannedOnce: true });
- await bgController.requestScan(getTabId()!);
+ await this.bgController.requestScan({ contentTabId: this.devtoolsAppController.contentTabId!, toolTabId: await getTabIdAsync()});
// The scan is done here so can calc issues found and issue type counts
// see newReport in reportListener
}
@@ -353,19 +355,19 @@ export class ScanSection extends React.Component<{}, ScanSectionState> {
{/* devtoolsController.exportXLS("last") }
+ onClick={() => this.devtoolsController.exportXLS("last") }
/> */}
{
- devtoolsController.setStoreReports(!this.state.storeReports);
+ this.devtoolsController.setStoreReports(!this.state.storeReports);
}}
/>
devtoolsController.exportXLS("all") }
+ onClick={() => this.devtoolsController.exportXLS("all") }
/>
{
selectionMode="manual"
selectedIndex={this.state.focusMode ? 0 : 1}
onChange={(newState: { index: string, name: "All" | "Focused", text: string }) => {
- devtoolsController.setFocusMode(newState.name === "Focused");
+ this.devtoolsController.setFocusMode(newState.name === "Focused");
}}
>
{
disabled={!this.state.reportContent}
iconDescription="Keyboard Checker Mode" tooltipPosition="left"
onClick={async () => {
- let settings = await bgController.getSettings();
+ let settings = await this.bgController.getSettings();
let newState :ViewState = JSON.parse(JSON.stringify(this.state.viewState));
newState.kcm = !newState.kcm;
let devtoolsAppController = getDevtoolsAppController();
@@ -438,7 +440,7 @@ export class ScanSection extends React.Component<{}, ScanSectionState> {
devtoolsAppController.closeSecondary();
}
}
- await devtoolsController.setViewState(newState);
+ await this.devtoolsController.setViewState(newState);
}}
size="sm"
kind="secondary"
@@ -495,10 +497,10 @@ export class ScanSection extends React.Component<{}, ScanSectionState> {
className= {totalCount === 0 ? "darkLink totalCountDisable" : "darkLink totalCountEnable"}
aria-disabled={totalCount === 0}
inline={true}
- onClick={() => {
- let appController = getDevtoolsAppController();
+ onClick={(evt: any) => {
getDevtoolsAppController().setSecondaryView("summary");
- appController.openSecondary("totalIssuesCount");
+ this.devtoolsAppController.openSecondary("totalIssuesCount");
+ evt.preventDefault();
}}>{totalCount} issues found
@@ -518,7 +520,7 @@ export class ScanSection extends React.Component<{}, ScanSectionState> {
this.setState({ confirmClearStored: false });
}).bind(this)}
onRequestSubmit={(() => {
- devtoolsController.clearStoredReports();
+ this.devtoolsController.clearStoredReports();
this.setState({
storedReportsCount: 0,
confirmClearStored: false
diff --git a/accessibility-checker-extension/src/ts/devtools/components/storedScreen.tsx b/accessibility-checker-extension/src/ts/devtools/components/storedScreen.tsx
index 053b508bc..94fe3e0bb 100644
--- a/accessibility-checker-extension/src/ts/devtools/components/storedScreen.tsx
+++ b/accessibility-checker-extension/src/ts/devtools/components/storedScreen.tsx
@@ -34,6 +34,7 @@ import { getDevtoolsController } from "../devtoolsController";
import { BrowserDetection } from '../../util/browserDetection';
import "./storedScreen.scss";
import { BasicTable } from "./BasicTable";
+import { getDevtoolsAppController } from "../devtoolsAppController";
interface IStoredScreenState {
storedReports: IStoredReportMeta[]
@@ -45,7 +46,8 @@ interface IStoredScreenProps {
}
export default class StoredScreen extends React.Component {
- private devtoolsController = getDevtoolsController();
+ private devtoolsAppController = getDevtoolsAppController();
+ private devtoolsController = getDevtoolsController(this.devtoolsAppController.toolTabId);
state: IStoredScreenState = {
storedReports: []
}
@@ -154,7 +156,7 @@ export default class StoredScreen extends React.Component scan.id === deleteScan.id);
newList.splice(idx, 1);
}
- await getDevtoolsController().setStoredReportsMeta(newList);
+ await this.devtoolsController.setStoredReportsMeta(newList);
this.setState({ deleteSelectedRows: undefined });
}}>
Delete
diff --git a/accessibility-checker-extension/src/ts/devtools/components/summaryScreen.tsx b/accessibility-checker-extension/src/ts/devtools/components/summaryScreen.tsx
index 21b5903d4..31db3df98 100644
--- a/accessibility-checker-extension/src/ts/devtools/components/summaryScreen.tsx
+++ b/accessibility-checker-extension/src/ts/devtools/components/summaryScreen.tsx
@@ -25,7 +25,6 @@
import { getBGController } from '../../background/backgroundController';
import { getDevtoolsAppController } from '../devtoolsAppController';
import { BrowserDetection } from '../../util/browserDetection';
- import { getTabId } from '../../util/tabId';
import "./summaryScreen.scss";
interface ISummaryScreenState {
@@ -38,34 +37,36 @@
}
- let bgController = getBGController();
- let appController = getDevtoolsAppController();
export default class SummaryScreen extends React.Component {
- private devtoolsController = getDevtoolsController();
+ private devtoolsAppController = getDevtoolsAppController();
+ private devtoolsController = getDevtoolsController(this.devtoolsAppController.toolTabId);
+ private bgController = getBGController();
+ private appController = getDevtoolsAppController();
state: ISummaryScreenState = {
ignoredIssues: []
}
async componentDidMount(): Promise {
let self = this;
+ let contentTabInfo = await this.bgController.getTabInfo(this.appController.contentTabId!);
this.devtoolsController.addReportListener(async (newState) => {
- let url = (await bgController.getTabInfo(getTabId())).url!;
- let alreadyIgnored = await bgController.getIgnore(url);
+ let url = contentTabInfo.url!;
+ let alreadyIgnored = await this.bgController.getIgnore(url);
self.setState({
ignoredIssues: alreadyIgnored,
report: newState,
reportMeta: await self.devtoolsController.getReportMeta() || undefined
});
})
- appController.addLevelFilterListener(() => {
+ this.appController.addLevelFilterListener(() => {
this.setState({});
})
- bgController.addIgnoreUpdateListener(async ({ url, issues }) => {
- if (url === (await bgController.getTabInfo(getTabId())).url) {
+ this.bgController.addIgnoreUpdateListener(async ({ url, issues }) => {
+ if (url === contentTabInfo.url) {
this.setState({ ignoredIssues: issues });
}
})
- let url = (await bgController.getTabInfo(getTabId())).url!;
- let alreadyIgnored = await bgController.getIgnore(url);
+ let url = contentTabInfo.url!;
+ let alreadyIgnored = await this.bgController.getIgnore(url);
this.setState({
ignoredIssues: alreadyIgnored,
report: await self.devtoolsController.getReport() || undefined,
@@ -148,11 +149,11 @@
{
- let checked = appController.getLevelFilters();
+ let checked = this.appController.getLevelFilters();
checked["Violation"] = !checked["Violation"];
- appController.setLevelFilters(checked);
+ this.appController.setLevelFilters(checked);
}}
>
@@ -167,11 +168,11 @@
{
- let checked = appController.getLevelFilters();
+ let checked = this.appController.getLevelFilters();
checked["Needs review"] = !checked["Needs review"];
- appController.setLevelFilters(checked);
+ this.appController.setLevelFilters(checked);
}}
>
@@ -184,11 +185,11 @@
{
- let checked = appController.getLevelFilters();
+ let checked = this.appController.getLevelFilters();
checked["Recommendation"] = !checked["Recommendation"];
- appController.setLevelFilters(checked);
+ this.appController.setLevelFilters(checked);
}}
>
diff --git a/accessibility-checker-extension/src/ts/devtools/devToolsApp.tsx b/accessibility-checker-extension/src/ts/devtools/devToolsApp.tsx
index 888d6f986..3f5841a7c 100644
--- a/accessibility-checker-extension/src/ts/devtools/devToolsApp.tsx
+++ b/accessibility-checker-extension/src/ts/devtools/devToolsApp.tsx
@@ -54,8 +54,8 @@ interface DevToolsAppState {
}
export class DevToolsApp extends React.Component
{
- bgController = getBGController();
- devtoolsAppController = getDevtoolsAppController();
+ private bgController = getBGController();
+ private devtoolsAppController = getDevtoolsAppController();
state : DevToolsAppState = {
secondaryView: "checkerViewAware",
diff --git a/accessibility-checker-extension/src/ts/devtools/devtoolsAppController.ts b/accessibility-checker-extension/src/ts/devtools/devtoolsAppController.ts
index c5d3dd055..b9d7980bc 100644
--- a/accessibility-checker-extension/src/ts/devtools/devtoolsAppController.ts
+++ b/accessibility-checker-extension/src/ts/devtools/devtoolsAppController.ts
@@ -19,7 +19,6 @@ import { getDevtoolsController } from "./devtoolsController";
export type eSecondaryView = "splash" | "summary" | "stored" | "help" | "kcm_overview" | "checkerViewAware";
-let devtoolsController = getDevtoolsController();
export type LevelFilters = {
[key in eFilterLevel]: boolean
@@ -46,13 +45,16 @@ export class DevtoolsAppController {
"Hidden": false
};
- constructor() {
- getDevtoolsController().addSelectedIssueListener(async () => {
+ private devToolsController;
+
+ constructor(public toolTabId: number, public contentTabId: number) {
+ this.devToolsController = getDevtoolsController(toolTabId);
+ this.devToolsController.addSelectedIssueListener(async () => {
if (!this.secondaryOpen) {
this.setSecondaryView("help");
}
});
- getDevtoolsController().addReportListener(async (report: IReport) => {
+ this.devToolsController.addReportListener(async (report: IReport) => {
if (!report) {
this.setSecondaryView("splash");
}
@@ -197,7 +199,7 @@ export class DevtoolsAppController {
console.error(err);
}
})($0)`, async (result: string) => {
- await devtoolsController.setSelectedElementPath(result, true);
+ await this.devToolsController.setSelectedElementPath(result, true);
});
});
chrome.devtools.inspectedWindow.eval(`inspect(document.documentElement);`);
@@ -226,9 +228,11 @@ export class DevtoolsAppController {
}
let singleton : DevtoolsAppController;
-export function getDevtoolsAppController() {
- if (!singleton) {
- singleton = new DevtoolsAppController();
+export function getDevtoolsAppController(toolTabId?: number, contentTabId?: number) {
+ if (!singleton && toolTabId && contentTabId) {
+ singleton = new DevtoolsAppController(toolTabId, contentTabId);
+ } else if (!singleton) {
+ throw new Error("Controller not initialized")
}
return singleton;
}
diff --git a/accessibility-checker-extension/src/ts/devtools/devtoolsController.ts b/accessibility-checker-extension/src/ts/devtools/devtoolsController.ts
index 6132adff6..32331bdee 100644
--- a/accessibility-checker-extension/src/ts/devtools/devtoolsController.ts
+++ b/accessibility-checker-extension/src/ts/devtools/devtoolsController.ts
@@ -20,7 +20,7 @@ import { CommonMessaging } from "../messaging/commonMessaging";
import { Controller, eControllerType, ListenerType } from "../messaging/controller";
import Config from "../util/config";
import { genReport } from "../util/htmlReport/genReport";
-import { getTabId } from "../util/tabId";
+import { getTabIdSync } from "../util/tabId";
import MultiScanData from "../util/xlsxReport/multiScanReport/xlsx/MultiScanData";
import MultiScanReport from "../util/xlsxReport/multiScanReport/xlsx/MultiScanReport";
@@ -55,6 +55,22 @@ export class DevtoolsController extends Controller {
///// Stored reports functions /////////////////////////////////////////
+ /**
+ * Wait for connection to open
+ */
+ public async awaitConnection(): Promise {
+ let resp = null;
+ do {
+ resp = await this.hook("awaitConnection", null, async () => {
+ return "OK";
+ })
+ if (!resp) {
+ await new Promise(resolve => setTimeout(resolve, 100));
+ }
+ } while (resp === null);
+ return resp;
+ }
+
/**
* Get stored reports
*/
@@ -249,9 +265,8 @@ export class DevtoolsController extends Controller {
let bgController = getBGController();
let settings = await bgController.getSettings();
if (report) {
- let tabId = getTabId();
- let tabInfo = await bgController.getTabInfo(tabId);
- let ignored: IIssue[] = await bgController.getIgnore(tabInfo.url!);
+ let contentTabInfo = await bgController.getTabInfo(this.contentTabId!);
+ let ignored: IIssue[] = await bgController.getIgnore(contentTabInfo.url!);
let newCounts = await this.getCountsWithHidden(report.counts, report.results, ignored);
const now = new Date().getTime();
devtoolsState!.lastReportMeta = {
@@ -260,17 +275,17 @@ export class DevtoolsController extends Controller {
label: `scan_${this.scanCounter++}`,
ruleset: settings.selected_archive.id,
guideline: settings.selected_ruleset.id,
- pageTitle: tabInfo.title!,
- pageURL: tabInfo.url!,
- screenshot: await bgController.getScreenshot(tabId),
+ pageTitle: contentTabInfo.title!,
+ pageURL: contentTabInfo.url!,
+ screenshot: await bgController.getScreenshot(this.contentTabId),
storedScanData: MultiScanData.issues_sheet_rows({
settings: settings,
report: report,
ignored: ignored,
- pageTitle: tabInfo.title!,
- pageURL: tabInfo.url!,
+ pageTitle: contentTabInfo.title!,
+ pageURL: contentTabInfo.url!,
timestamp: now+"",
- rulesets: await bgController.getRulesets(tabId!)
+ rulesets: await bgController.getRulesets(this.contentTabId!)
}),
testedUniqueElements: report.testedUniqueElements,
counts: newCounts
@@ -617,10 +632,12 @@ export class DevtoolsController extends Controller {
}
private async htmlReportHandler() {
+ if (!this.contentTabId) {
+ throw new Error("Cannot call this function directly from remote controllers")
+ }
let bgController = await getBGController();
- let tabId = getTabId();
- let rulesets = await bgController.getRulesets(tabId!);
- let tabInfo = await bgController.getTabInfo(getTabId());
+ let rulesets = await bgController.getRulesets(this.contentTabId);
+ let tabInfo = await bgController.getTabInfo(this.contentTabId);
if (devtoolsState?.lastReport && rulesets) {
let reportObj: any = {
tabURL: tabInfo.url,
@@ -720,8 +737,8 @@ export class DevtoolsController extends Controller {
///////////////////////////////////////////////////////////////////////////
///// PRIVATE API /////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
- constructor(isContentScript: boolean, type: eControllerType, tabId?: number) {
- super(type, { type: "devTools", tabId: (tabId || getTabId())!, relay: isContentScript}, "DT");
+ constructor(toolTabId: number, isContentScript: boolean, type: eControllerType, private contentTabId?: number) {
+ super(type, { type: "devTools", tabId: (toolTabId || getTabIdSync())!, relay: isContentScript}, "DT");
if (type === "local") {
let self = this;
devtoolsState = {
@@ -765,7 +782,8 @@ export class DevtoolsController extends Controller {
"DT_exportXLS": async(msgBody) => self.exportXLS(msgBody.content),
"DT_setScanningState": async(msgBody) => self.setScanningState(msgBody.content),
"DT_setActivePanel": async(msgBody) => self.setActivePanel(msgBody.content),
- "DT_getActivePanel": async() => self.getActivePanel()
+ "DT_getActivePanel": async() => self.getActivePanel(),
+ "DT_awaitConnection": async() => self.awaitConnection()
}
// Hook the above definitions
@@ -807,15 +825,20 @@ let singletons : {
* Get a devtools controller
* @param relay
* @param type Set to false if sending messages in the same context (e.g., from devtools panel to devtools main)
- * @param tabId
+ * @param toolTabId
* @returns
*/
-export function getDevtoolsController(isContentScript?: boolean, type?: eControllerType, tabId?: number) {
- if (!singletons[(tabId || getTabId())!]) {
+export function getDevtoolsController(toolTabId: number, isContentScript?: boolean, type?: eControllerType, contentTabId?: number) {
+ type = type || "remote";
+ if (!singletons[toolTabId] && contentTabId) {
// console.log("Creating devtools controller", type);
- singletons[(tabId || getTabId())!] = new DevtoolsController(isContentScript === true, type || "remote", tabId);
+ singletons[toolTabId] = new DevtoolsController(toolTabId, isContentScript === true, type, contentTabId);
+ } else if (!singletons[toolTabId] && type === "remote") {
+ singletons[toolTabId] = new DevtoolsController(toolTabId, isContentScript === true, type);
+ } else if (!singletons[toolTabId]) {
+ throw new Error("Initialization error");
}
- return singletons[(tabId || getTabId())!];
+ return singletons[toolTabId];
}
diff --git a/accessibility-checker-extension/src/ts/devtools/index.tsx b/accessibility-checker-extension/src/ts/devtools/index.tsx
index e5829fba2..46aa690e1 100644
--- a/accessibility-checker-extension/src/ts/devtools/index.tsx
+++ b/accessibility-checker-extension/src/ts/devtools/index.tsx
@@ -15,9 +15,12 @@
*****************************************************************************/
import Config from "../util/config";
+import { getTabIdSync } from "../util/tabId";
import { getDevtoolsController } from "./devtoolsController";
let localStr = (Config.engineEndpoint && Config.engineEndpoint.includes("localhost") && " (local)") || "";
let devStr = (Config.workspace && Config.workspace === "development" && " (dev)") || "";
+let devtoolsController = getDevtoolsController(getTabIdSync()!, false, "local", getTabIdSync()!);
+
chrome.devtools.panels.elements.createSidebarPane("Accessibility Checker"+devStr+localStr,
function(newPanel) {
//sidebar initialization code here
@@ -42,4 +45,3 @@ chrome.devtools.panels.create("Accessibility Assessment"+devStr+localStr, "", "d
}
);
-let devtoolsController = getDevtoolsController(false, "local");
diff --git a/accessibility-checker-extension/src/ts/devtools/indexElements.tsx b/accessibility-checker-extension/src/ts/devtools/indexElements.tsx
index d96d55a1f..783861392 100644
--- a/accessibility-checker-extension/src/ts/devtools/indexElements.tsx
+++ b/accessibility-checker-extension/src/ts/devtools/indexElements.tsx
@@ -18,9 +18,26 @@ import * as React from 'react';
import ReactDOM from 'react-dom';
import { DevToolsApp } from './devToolsApp';
import { getDevtoolsAppController } from './devtoolsAppController';
+import { getDevtoolsController } from './devtoolsController';
+import { getTabIdAsync } from '../util/tabId';
-getDevtoolsAppController();
+(async () => {
+ if (document?.location?.protocol === "chrome-extension:" && document?.location?.search.startsWith("?index=")) {
+ let index = parseInt(decodeURIComponent(document.location.search.substring("?index=".length)));
+ let tabRef = (await chrome.tabs.query({ index }))[0];
+ let contentTabId = tabRef.id;
+ let toolTabId = await getTabIdAsync();
+ let dtc = getDevtoolsController(toolTabId, false, "local", contentTabId);
+ getDevtoolsAppController(toolTabId, contentTabId);
+ await dtc.awaitConnection();
+ } else {
+ let toolTabId = await getTabIdAsync();
+ let dtc = getDevtoolsController(toolTabId, false, "remote", toolTabId)
+ getDevtoolsAppController(toolTabId, toolTabId);
+ await dtc.awaitConnection();
+ }
-ReactDOM.render(
- , document.getElementById('pageapp-root'));
+ ReactDOM.render(
+ , document.getElementById('pageapp-root'));
+})();
\ No newline at end of file
diff --git a/accessibility-checker-extension/src/ts/devtools/indexMain.tsx b/accessibility-checker-extension/src/ts/devtools/indexMain.tsx
index ce4c919b8..067d5702a 100644
--- a/accessibility-checker-extension/src/ts/devtools/indexMain.tsx
+++ b/accessibility-checker-extension/src/ts/devtools/indexMain.tsx
@@ -18,9 +18,29 @@ import * as React from 'react';
import ReactDOM from 'react-dom';
import { DevToolsApp } from './devToolsApp';
import { getDevtoolsAppController } from './devtoolsAppController';
+import { getDevtoolsController } from './devtoolsController';
+import { getTabIdAsync } from '../util/tabId';
-getDevtoolsAppController();
+(async () => {
+ if (document?.location?.protocol === "chrome-extension:" && document?.location?.search.startsWith("?index=")) {
+ let index = parseInt(decodeURIComponent(document.location.search.substring("?index=".length)));
+ let tabRef = (await chrome.tabs.query({ index }))[0];
+ let contentTabId = tabRef.id;
+ let toolTabId = await getTabIdAsync();
+ if (!toolTabId || !contentTabId) {
+ console.warn("Test initializing", toolTabId, contentTabId);
+ }
+ let dtc = getDevtoolsController(toolTabId, false, "local", contentTabId);
+ getDevtoolsAppController(toolTabId, contentTabId);
+ await dtc.awaitConnection();
+ } else {
+ let toolTabId = await getTabIdAsync();
+ let dtc = getDevtoolsController(toolTabId, false, "remote", toolTabId)
+ getDevtoolsAppController(toolTabId, toolTabId);
+ await dtc.awaitConnection();
+ }
-ReactDOM.render(
- , document.getElementById('pageapp-root'));
+ ReactDOM.render(
+ , document.getElementById('pageapp-root'));
+})();
\ No newline at end of file
diff --git a/accessibility-checker-extension/src/ts/messaging/controller.ts b/accessibility-checker-extension/src/ts/messaging/controller.ts
index 5680a8404..69788a327 100644
--- a/accessibility-checker-extension/src/ts/messaging/controller.ts
+++ b/accessibility-checker-extension/src/ts/messaging/controller.ts
@@ -16,7 +16,7 @@
import { IMessage, MsgDestType } from "../interfaces/interfaces";
import Config from "../util/config";
-import { getTabId } from "../util/tabId";
+import { getTabIdAsync } from "../util/tabId";
import { CommonMessaging } from "./commonMessaging";
export type eControllerType = "local" | "remote";
@@ -61,7 +61,7 @@ export class Controller {
|| (message.dest.type === "background" && this.ctrlDest.type === "background")) {
this.notifyEventListeners(msgId, this.ctrlDest.tabId, message.content);
}
- }, [msgId], getTabId());
+ }, [msgId], await getTabIdAsync());
}
}
@@ -159,7 +159,7 @@ export class Controller {
) {
CommonMessaging.addMsgListener((message: IMessage, senderTabId?: number) => {
return func(message, senderTabId);
- }, msgNames, getTabId());
+ }, msgNames, await getTabIdAsync());
}
}
diff --git a/accessibility-checker-extension/src/ts/options/OptionsApp.tsx b/accessibility-checker-extension/src/ts/options/OptionsApp.tsx
index 098ca8727..8b9ca458d 100644
--- a/accessibility-checker-extension/src/ts/options/OptionsApp.tsx
+++ b/accessibility-checker-extension/src/ts/options/OptionsApp.tsx
@@ -178,7 +178,7 @@ export class OptionsApp extends React.Component<{}, OptionsAppState> {
let tabStoredScans = (await getBGController().getSessionState()).tabStoredCount;
for (const tabId in tabStoredScans) {
if (tabStoredScans[tabId] > 0) {
- getDevtoolsController(false, "remote", parseInt(tabId)).clearStoredReports();
+ getDevtoolsController(parseInt(tabId), false, "remote").clearStoredReports();
}
}
this.setState({storedScansExist: false});
diff --git a/accessibility-checker-extension/src/ts/util/tabId.ts b/accessibility-checker-extension/src/ts/util/tabId.ts
index 4f745dacb..2e4489b33 100644
--- a/accessibility-checker-extension/src/ts/util/tabId.ts
+++ b/accessibility-checker-extension/src/ts/util/tabId.ts
@@ -14,10 +14,21 @@
limitations under the License.
*****************************************************************************/
-export function getTabId() {
+import { getBGController } from "../background/backgroundController";
+
+export function getTabIdSync() {
if (chrome && chrome.devtools && chrome.devtools.inspectedWindow && chrome.devtools.inspectedWindow.tabId) {
return chrome.devtools.inspectedWindow.tabId;
} else {
return undefined;
}
+}
+
+export async function getTabIdAsync() {
+ let tabId = getTabIdSync();
+ if (typeof tabId !== "undefined") {
+ return tabId;
+ } else {
+ return getBGController().getTabId();
+ }
}
\ No newline at end of file
diff --git a/accessibility-checker-extension/test/.achecker/baselines/Accessibility Assessment Panel default view is accessible.json b/accessibility-checker-extension/test/.achecker/baselines/Accessibility Assessment Panel default view is accessible.json
new file mode 100644
index 000000000..71020a55b
--- /dev/null
+++ b/accessibility-checker-extension/test/.achecker/baselines/Accessibility Assessment Panel default view is accessible.json
@@ -0,0 +1,208 @@
+{
+ "results": [
+ {
+ "ruleId": "aria_attribute_valid",
+ "value": [
+ "VIOLATION",
+ "FAIL"
+ ],
+ "path": {
+ "dom": "/html[1]/body[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div[2]/div[2]/div[1]/div[1]/div[2]/a[1]",
+ "aria": "/document[1]/main[1]/link[1]"
+ },
+ "ruleTime": 0,
+ "reasonId": "Fail_invalid_implicit_role_attr",
+ "message": "The ARIA attributes \"aria-disabled\" are not valid for the element with implicit ARIA role \"link\"",
+ "messageArgs": [
+ "aria-disabled",
+ "a",
+ "link"
+ ],
+ "apiArgs": [],
+ "bounds": {
+ "left": 491,
+ "top": 86,
+ "height": 19,
+ "width": 94
+ },
+ "snippet": "",
+ "category": "Accessibility",
+ "ignored": true,
+ "level": "violation",
+ "help": "https://able.ibm.com/rules/archives/2024.02.02/doc/en-US/aria_attribute_valid.html#%7B%22message%22%3A%22The%20ARIA%20attributes%20%5C%22aria-disabled%5C%22%20are%20not%20valid%20for%20the%20element%20%3Ca%3E%20with%20implicit%20ARIA%20role%20%5C%22link%5C%22%22%2C%22snippet%22%3A%22%3Ca%20aria-disabled%3D%5C%22true%5C%22%20id%3D%5C%22totalIssuesCount%5C%22%20href%3D%5C%22%230%5C%22%20class%3D%5C%22cds--link%20darkLink%20totalCountDisable%20cds--link--inline%5C%22%3E%22%2C%22value%22%3A%5B%22VIOLATION%22%2C%22FAIL%22%5D%2C%22reasonId%22%3A%22Fail_invalid_implicit_role_attr%22%2C%22ruleId%22%3A%22aria_attribute_valid%22%2C%22msgArgs%22%3A%5B%22aria-disabled%22%2C%22a%22%2C%22link%22%5D%7D"
+ },
+ {
+ "ruleId": "aria_attribute_valid",
+ "value": [
+ "VIOLATION",
+ "FAIL"
+ ],
+ "path": {
+ "dom": "/html[1]/body[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div[4]/div[1]/div[1]/div[2]/div[1]/div[1]",
+ "aria": "/document[1]/main[1]/generic[1]"
+ },
+ "ruleTime": 0,
+ "reasonId": "Fail_invalid_implicit_role_attr",
+ "message": "The ARIA attributes \"aria-label\" are not valid for the element with implicit ARIA role \"generic\"",
+ "messageArgs": [
+ "aria-label",
+ "div",
+ "generic"
+ ],
+ "apiArgs": [],
+ "bounds": {
+ "left": 34,
+ "top": 111,
+ "height": 32,
+ "width": 160
+ },
+ "snippet": "
",
+ "category": "Accessibility",
+ "ignored": true,
+ "level": "violation",
+ "help": "https://able.ibm.com/rules/archives/2024.02.02/doc/en-US/aria_attribute_valid.html#%7B%22message%22%3A%22The%20ARIA%20attributes%20%5C%22aria-label%5C%22%20are%20not%20valid%20for%20the%20element%20%3Cdiv%3E%20with%20implicit%20ARIA%20role%20%5C%22generic%5C%22%22%2C%22snippet%22%3A%22%3Cdiv%20class%3D%5C%22cds--dropdown%20cds--dropdown--disabled%20cds--dropdown--sm%20cds--list-box%20cds--list-box--sm%5C%22%20id%3D%5C%22reportView%5C%22%20aria-label%3D%5C%22Select%20report%20view%5C%22%3E%22%2C%22value%22%3A%5B%22VIOLATION%22%2C%22FAIL%22%5D%2C%22reasonId%22%3A%22Fail_invalid_implicit_role_attr%22%2C%22ruleId%22%3A%22aria_attribute_valid%22%2C%22msgArgs%22%3A%5B%22aria-label%22%2C%22div%22%2C%22generic%22%5D%7D"
+ },
+ {
+ "ruleId": "aria_id_unique",
+ "value": [
+ "VIOLATION",
+ "FAIL"
+ ],
+ "path": {
+ "dom": "/html[1]/body[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div[4]/div[1]/div[1]/div[2]/div[1]/div[1]/div[1]",
+ "aria": "/document[1]/main[1]/generic[1]/listbox[1]"
+ },
+ "ruleTime": 0,
+ "reasonId": "Fail_1",
+ "message": "The 'id' \"downshift-3-label\" specified for the ARIA property 'aria-labelledby' value is not valid",
+ "messageArgs": [
+ "downshift-3-label",
+ "aria-labelledby",
+ "div"
+ ],
+ "apiArgs": [],
+ "bounds": {
+ "left": 35,
+ "top": 143,
+ "height": 0,
+ "width": 158
+ },
+ "snippet": "