Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 68 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,75 @@
with:
node-version: 22.x

- run: npm install
- run: npx playwright install
- run: npm run type-check
- run: npm run build
- run: npm run lint
- run: npm run format
- name: "Run tests"
- name: Install dependencies
run: npm install

- name: Install Playwright browsers
run: npx playwright install

- name: Type check
run: npm run type-check

- name: Build
run: npm run build

- name: Lint
run: npm run lint

- name: Format check
run: npm run format

- name: Run tests
run: npm run test

- name: Check for unstaged changes
run: |
git status --porcelain
git diff-index --quiet HEAD -- || exit 1

playwright-tools:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Use Node.js 22
uses: actions/setup-node@v3
with:
node-version: 22.x

- name: Install root dependencies
run: npm install

- name: Install dependencies
working-directory: tools/playwright
run: npm install

- name: Install Playwright browsers
working-directory: tools/playwright
run: npx playwright install --with-deps chromium

- name: Type check
working-directory: tools/playwright
run: npm run type-check

- name: Build
working-directory: tools/playwright
run: npm run build

- name: Lint
working-directory: tools/playwright
run: npm run lint

- name: Format check
working-directory: tools/playwright
run: npm run format

- name: Run tests
working-directory: tools/playwright
run: npm run test
- name: "Check for unstaged changes"

- name: Check for unstaged changes
run: |
git status --porcelain
git diff-index --quiet HEAD -- || exit 1

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Ignore artifacts:
dist
node_modules
test-results
.test-output
*.yml
21 changes: 21 additions & 0 deletions src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,27 @@ export class AbleDOM {

constructor(win: Window, props: AbleDOMProps = {}) {
this._win = win;

// Check if testing mode is requested via window flag
// 1 = headed (force headless=false), 2 = headless (force headless=true), 3 = exact (no override)
const testingMode = (
win as Window & { ableDOMInstanceForTestingNeeded?: number }
).ableDOMInstanceForTestingNeeded;
if (testingMode === 1 || testingMode === 2 || testingMode === 3) {
// Expose the instance for testing
(
win as Window & { ableDOMInstanceForTesting?: AbleDOM }
).ableDOMInstanceForTesting = this;

// Override headless prop based on mode
if (testingMode === 1) {
props = { ...props, headless: false };
} else if (testingMode === 2) {
props = { ...props, headless: true };
}
// testingMode === 3: use props as-is
}

this._props = props;

const _elementsToValidate: Set<HTMLElementWithAbleDOM> = new Set();
Expand Down
17 changes: 17 additions & 0 deletions tests/testingMode/testingMode-exact.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Testing Mode - Exact (3)</title>
<script>
// Set the testing mode flag BEFORE AbleDOM loads
window.ableDOMInstanceForTestingNeeded = 3;
</script>
<script type="module" src="./testingMode-exact.ts"></script>
</head>
<body>
<h1>Testing Mode - Exact</h1>
<button id="button-1">Button1</button>
</body>
</html>
16 changes: 16 additions & 0 deletions tests/testingMode/testingMode-exact.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*!
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/

import { AbleDOM, FocusableElementLabelRule } from "abledom";
import { initIdleProp, getAbleDOMCallbacks } from "../utils";

// Create AbleDOM with headless: false (should stay false with mode 3)
const ableDOM = new AbleDOM(window, {
headless: false,
callbacks: getAbleDOMCallbacks(),
});
initIdleProp(ableDOM);
ableDOM.addRule(new FocusableElementLabelRule());
ableDOM.start();
17 changes: 17 additions & 0 deletions tests/testingMode/testingMode-headed.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Testing Mode - Headed (1)</title>
<script>
// Set the testing mode flag BEFORE AbleDOM loads
window.ableDOMInstanceForTestingNeeded = 1;
</script>
<script type="module" src="./testingMode-headed.ts"></script>
</head>
<body>
<h1>Testing Mode - Headed</h1>
<button id="button-1">Button1</button>
</body>
</html>
16 changes: 16 additions & 0 deletions tests/testingMode/testingMode-headed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*!
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/

import { AbleDOM, FocusableElementLabelRule } from "abledom";
import { initIdleProp, getAbleDOMCallbacks } from "../utils";

// Create AbleDOM with headless: true (should be overridden to false by mode 1)
const ableDOM = new AbleDOM(window, {
headless: true,
callbacks: getAbleDOMCallbacks(),
});
initIdleProp(ableDOM);
ableDOM.addRule(new FocusableElementLabelRule());
ableDOM.start();
17 changes: 17 additions & 0 deletions tests/testingMode/testingMode-headless.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Testing Mode - Headless (2)</title>
<script>
// Set the testing mode flag BEFORE AbleDOM loads
window.ableDOMInstanceForTestingNeeded = 2;
</script>
<script type="module" src="./testingMode-headless.ts"></script>
</head>
<body>
<h1>Testing Mode - Headless</h1>
<button id="button-1">Button1</button>
</body>
</html>
16 changes: 16 additions & 0 deletions tests/testingMode/testingMode-headless.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*!
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/

import { AbleDOM, FocusableElementLabelRule } from "abledom";
import { initIdleProp, getAbleDOMCallbacks } from "../utils";

// Create AbleDOM with headless: false (should be overridden to true by mode 2)
const ableDOM = new AbleDOM(window, {
headless: false,
callbacks: getAbleDOMCallbacks(),
});
initIdleProp(ableDOM);
ableDOM.addRule(new FocusableElementLabelRule());
ableDOM.start();
14 changes: 14 additions & 0 deletions tests/testingMode/testingMode-none.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Testing Mode - None (no flag)</title>
<!-- No ableDOMInstanceForTestingNeeded flag set -->
<script type="module" src="./testingMode-none.ts"></script>
</head>
<body>
<h1>Testing Mode - None</h1>
<button id="button-1">Button1</button>
</body>
</html>
16 changes: 16 additions & 0 deletions tests/testingMode/testingMode-none.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*!
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/

import { AbleDOM, FocusableElementLabelRule } from "abledom";
import { initIdleProp, getAbleDOMCallbacks } from "../utils";

// Create AbleDOM without any testing mode flag
const ableDOM = new AbleDOM(window, {
headless: true,
callbacks: getAbleDOMCallbacks(),
});
initIdleProp(ableDOM);
ableDOM.addRule(new FocusableElementLabelRule());
ableDOM.start();
Loading