chore: setup Playwright & add base test (#60)

This commit is contained in:
Oleksandr Fediashov 2023-12-21 10:41:29 +01:00 коммит произвёл GitHub
Родитель fc7ea86da9
Коммит 5c65d0d010
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
11 изменённых файлов: 4537 добавлений и 61 удалений

19
.github/workflows/ci.yml поставляемый
Просмотреть файл

@ -24,16 +24,27 @@ jobs:
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- name: Use Node.js 16
- name: Use Node.js 18
uses: actions/setup-node@v1
with:
node-version: 16.x
node-version: 18.x
- run: npm install
- run: npm ci
- run: npm run format
- run: npm run lint
- run: npm run build
- name: Install Playwright Browsers
run: npx playwright install --with-deps
- name: Run Playwright tests
run: npx playwright test
- uses: actions/upload-artifact@v3
with:
name: playwright-report
path: playwright-report/
retention-days: 30
- name: "Check for unstaged changes"
run: |
git status --porcelain

8
.gitignore поставляемый
Просмотреть файл

@ -2,4 +2,10 @@ dist
node_modules
# VScode devcontainer
.devcontainer
.devcontainer
# Playwright
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/

4
.ladle/config.mjs Normal file
Просмотреть файл

@ -0,0 +1,4 @@
/** @type {import('@ladle/react').UserConfig} */
export default {
stories: "tests/**/*.stories.tsx",
};

4440
package-lock.json сгенерированный

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -20,12 +20,17 @@
"bundle-size": "npm run build && monosize measure",
"format": "prettier --check .",
"format:fix": "prettier --write .",
"test": "playwright test",
"test:serve": "ladle serve --port 3000",
"lint": "eslint src/",
"lint:fix": "eslint src/ --fix",
"prepublishOnly": "npm run lint && npm run format && npm run build",
"release": "release-it"
},
"devDependencies": {
"@ladle/react": "^4.0.2",
"@playwright/test": "^1.40.1",
"playwright": "^1.40.1",
"@typescript-eslint/eslint-plugin": "^5.4.0",
"@typescript-eslint/parser": "^5.4.0",
"eslint": "^8.2.0",

30
playwright.config.ts Normal file
Просмотреть файл

@ -0,0 +1,30 @@
import { defineConfig, devices } from "@playwright/test";
export default defineConfig({
testDir: "./tests",
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: "html",
use: {
baseURL: "http://localhost:3000",
trace: "on-first-retry",
},
projects: [
{
name: "chromium",
use: { ...devices["Desktop Chrome"] },
},
],
webServer: {
command: "npm run test:serve",
url: "http://localhost:3000",
reuseExistingServer: !process.env.CI,
stdout: "pipe",
stderr: "pipe",
},
});

Просмотреть файл

@ -3,19 +3,17 @@
* Licensed under the MIT License.
*/
export {
Keyborg,
KeyborgCallback,
createKeyborg,
disposeKeyborg,
} from "./Keyborg";
export type { Keyborg, KeyborgCallback } from "./Keyborg";
export { createKeyborg, disposeKeyborg } from "./Keyborg";
export type {
KeyborgFocusInEvent,
KeyborgFocusInEventDetails,
} from "./FocusEvent";
export {
getLastFocusedProgrammatically,
nativeFocus,
KEYBORG_FOCUSIN,
KeyborgFocusInEvent,
KeyborgFocusInEventDetails,
} from "./FocusEvent";
export const version = process.env.PKG_VERSION;

Просмотреть файл

@ -0,0 +1,27 @@
import { test, expect } from "@playwright/test";
test("Buttons scenario", async ({ page }) => {
await page.goto("/?mode=preview&story=focus-behavior--buttons");
await expect(page.getByTestId("keyboard-mode")).toContainText("false");
// Click the button [nav by mouse]
await page.getByText("Button A").click();
await expect(page.getByTestId("keyboard-mode")).toContainText("false");
// Press Tab [nav by keyboard]
await page.keyboard.press("Tab");
expect(await page.locator("*:focus")).toHaveText("Button B");
await expect(page.getByTestId("keyboard-mode")).toContainText("true");
// Press Tab [nav by keyboard]
await page.keyboard.press("Tab");
expect(await page.locator("*:focus")).toHaveText("Button C");
await expect(page.getByTestId("keyboard-mode")).toContainText("true");
// Click the button [nav by mouse]
await page.getByText("Button B").click();
await expect(page.getByTestId("keyboard-mode")).toContainText("false");
});

Просмотреть файл

@ -0,0 +1,40 @@
import * as React from "react";
import { createKeyborg } from "../src";
function KeyboardMode() {
const [isNavigatingWithKeyboard, setIsNavigatingWithKeyboard] =
React.useState(false);
const keyborg = createKeyborg(window);
React.useEffect(() => {
setIsNavigatingWithKeyboard(keyborg.isNavigatingWithKeyboard());
keyborg.subscribe(setIsNavigatingWithKeyboard);
return () => keyborg.unsubscribe(setIsNavigatingWithKeyboard);
}, [keyborg]);
return (
<div style={{ border: "2px solid grey", padding: 5 }}>
Is navigating with keyboard:{" "}
<code data-testid="keyboard-mode">
{isNavigatingWithKeyboard.toString()}
</code>
</div>
);
}
export const Buttons = () => (
<div style={{ display: "flex", flexDirection: "column", gap: 20 }}>
<h1>Focus Behavior with Buttons</h1>
<div
style={{ border: "2px solid blue", display: "flex", gap: 5, padding: 20 }}
>
<button>Button A</button>
<button>Button B</button>
<button>Button C</button>
</div>
<KeyboardMode />
</div>
);

Просмотреть файл

@ -2,7 +2,9 @@
"compilerOptions": {
"declaration": true,
"noResolve": false,
"jsx": "preserve",
"module": "ES2015",
"moduleResolution": "node",
"target": "ES2019",
"noImplicitAny": true,
"noImplicitReturns": true,
@ -15,6 +17,6 @@
"outDir": "./dist/",
"lib": ["DOM", "ESNext"]
},
"include": ["./src/**/*"],
"include": ["./src/**/*", "./tests/**/*", "./playwright.config.ts"],
"exclude": ["dist", "node_modules"]
}

7
vite.config.mts Normal file
Просмотреть файл

@ -0,0 +1,7 @@
import { defineConfig } from "vite";
export default defineConfig({
define: {
"process.env.PKG_VERSION": JSON.stringify("local"),
},
});