diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml
index b7155f1..5634ea3 100644
--- a/.github/workflows/pipeline.yml
+++ b/.github/workflows/pipeline.yml
@@ -63,8 +63,23 @@ jobs:
- uses: actions/upload-artifact@v3
if: ${{ failure() }}
with:
- name: playwright-test-results
- path: test-results
+ name: playwright-e2e-test-results
+ path: tests/e2e/playwright-report
+
+ - name: Run A11y tests
+ run: npm run test:a11y
+ env:
+ # Use a different port (from the one used with E2E tests) to workaround problem in CI/GitHub Actions,
+ # starting to occur with playwright/test 1.28.0:
+ # Error: http://localhost:4173 is already used ...
+ # See https://github.com/digitalservicebund/typescript-vite-application-template/actions/runs/3486985178/jobs/5834089375
+ VITE_PORT: 4183
+
+ - uses: actions/upload-artifact@v3
+ if: ${{ failure() }}
+ with:
+ name: playwright-a11y-test-results
+ path: tests/a11y/playwright-report
- name: Build an image from Dockerfile
run: |
diff --git a/.gitignore b/.gitignore
index 9d816dd..4b483a3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -148,10 +148,11 @@ dist
# Playwright
/test-results/
/playwright-report/
+**/playwright-report/
/playwright/.cache/
# Lefthook
lefthook-local.yml
# Talisman
-talisman_report
\ No newline at end of file
+talisman_report
diff --git a/.talismanrc b/.talismanrc
index 30c3411..cb23934 100644
--- a/.talismanrc
+++ b/.talismanrc
@@ -1,6 +1,6 @@
fileignoreconfig:
- filename: .github/workflows/pipeline.yml
- checksum: d08390039a10da00501e4278d261ee59fa09193a33893e01daf91d4c5015bf2d
+ checksum: dec3b1cb74779a0b9b6aecfc2d0a79200655838deb928593e3f9648f2fcabbfa
- filename: .github/workflows/scan.yml
checksum: b06430d20570ad4ce61e6078af8a2851ef1c1bf832f0a4f70c490bde1f533cdd
- filename: README.md
diff --git a/app/routes/_index.tsx b/app/routes/_index.tsx
index fe2032b..3a4d1db 100644
--- a/app/routes/_index.tsx
+++ b/app/routes/_index.tsx
@@ -9,11 +9,11 @@ export const meta: MetaFunction = () => {
export default function Index() {
return (
-
+
Hello DigitalService!
-
+
);
}
diff --git a/package-lock.json b/package-lock.json
index c9f79aa..1e20800 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18,6 +18,7 @@
"tailwindcss": "^3.3.4"
},
"devDependencies": {
+ "@axe-core/playwright": "^4.8.1",
"@playwright/test": "^1.39.0",
"@remix-run/dev": "^2.1.0",
"@remix-run/eslint-config": "^2.1.0",
@@ -78,6 +79,18 @@
"node": ">=6.0.0"
}
},
+ "node_modules/@axe-core/playwright": {
+ "version": "4.8.1",
+ "resolved": "https://registry.npmjs.org/@axe-core/playwright/-/playwright-4.8.1.tgz",
+ "integrity": "sha512-KC1X++UdRAwMLRvB+BIKFheyLHUnbJTL0t0Wbv6TJMozn2V2QyEtAcN6jyUiudtGiLUGhHCtj/eWorBnVZ4dAA==",
+ "dev": true,
+ "dependencies": {
+ "axe-core": "~4.8.2"
+ },
+ "peerDependencies": {
+ "playwright-core": ">= 1.0.0"
+ }
+ },
"node_modules/@babel/code-frame": {
"version": "7.22.13",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
diff --git a/package.json b/package.json
index 176dd54..8fe7ec1 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,8 @@
"typecheck": "tsc",
"test": "jest test",
"test:generate-coverage": "jest --coverage",
- "test:e2e": "playwright test",
+ "test:e2e": "playwright test --config=tests/e2e/playwright.config.ts",
+ "test:a11y": "playwright test --config=tests/a11y/playwright.config.ts",
"lint:check": "eslint --ext .js,.ts --ignore-path .gitignore .",
"lint:fix": "npm run lint:check -- --fix",
"format:check": "prettier --check .",
@@ -32,6 +33,7 @@
"tailwindcss": "^3.3.4"
},
"devDependencies": {
+ "@axe-core/playwright": "^4.8.1",
"@playwright/test": "^1.39.0",
"@remix-run/dev": "^2.1.0",
"@remix-run/eslint-config": "^2.1.0",
diff --git a/tests/a11y/example.spec.ts b/tests/a11y/example.spec.ts
new file mode 100644
index 0000000..6c7ea44
--- /dev/null
+++ b/tests/a11y/example.spec.ts
@@ -0,0 +1,14 @@
+import { test, expect } from "@playwright/test";
+import AxeBuilder from "@axe-core/playwright";
+
+test.describe("index", () => {
+ test("should not have any automatically detectable accessibility issues", async ({
+ page,
+ }) => {
+ await page.goto("/");
+
+ const accessibilityScanResults = await new AxeBuilder({ page }).analyze();
+
+ expect(accessibilityScanResults.violations).toEqual([]);
+ });
+});
diff --git a/playwright.config.ts b/tests/a11y/playwright.config.ts
similarity index 93%
rename from playwright.config.ts
rename to tests/a11y/playwright.config.ts
index db500df..60e8227 100644
--- a/playwright.config.ts
+++ b/tests/a11y/playwright.config.ts
@@ -8,7 +8,7 @@ import dotenv from "dotenv";
// Load both .env and test.env
dotenv.config();
-dotenv.config({ path: "./tests/test.env" });
+dotenv.config({ path: "../test.env" });
const useDefaultBaseUrl = ["", undefined].includes(process.env.E2E_BASE_URL);
const baseURL = useDefaultBaseUrl
@@ -19,7 +19,7 @@ const baseURL = useDefaultBaseUrl
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
- testDir: "./tests/e2e",
+ testDir: ".",
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
@@ -29,7 +29,14 @@ export default defineConfig({
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
- reporter: "html",
+ reporter: [
+ [
+ "html",
+ {
+ outputFolder: "./playwright-report",
+ },
+ ],
+ ],
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto("/")`. */
diff --git a/tests/e2e/playwright.config.ts b/tests/e2e/playwright.config.ts
new file mode 100644
index 0000000..099922e
--- /dev/null
+++ b/tests/e2e/playwright.config.ts
@@ -0,0 +1,91 @@
+import { defineConfig, devices } from "@playwright/test";
+import dotenv from "dotenv";
+
+/**
+ * Read environment variables from file.
+ * https://github.com/motdotla/dotenv
+ */
+
+// Load both .env and test.env
+dotenv.config();
+dotenv.config({ path: "../test.env" });
+
+const useDefaultBaseUrl = ["", undefined].includes(process.env.E2E_BASE_URL);
+const baseURL = useDefaultBaseUrl
+ ? "http://127.0.0.1:3000"
+ : process.env.E2E_BASE_URL;
+
+/**
+ * See https://playwright.dev/docs/test-configuration.
+ */
+export default defineConfig({
+ testDir: ".",
+ /* Run tests in files in parallel */
+ fullyParallel: true,
+ /* Fail the build on CI if you accidentally left test.only in the source code. */
+ forbidOnly: !!process.env.CI,
+ /* Retry on CI only */
+ retries: process.env.CI ? 2 : 0,
+ /* Opt out of parallel tests on CI. */
+ workers: process.env.CI ? 1 : undefined,
+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
+ reporter: [
+ [
+ "html",
+ {
+ outputFolder: "./playwright-report",
+ },
+ ],
+ ] /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */,
+ use: {
+ /* Base URL to use in actions like `await page.goto("/")`. */
+ baseURL,
+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
+ trace: "on-first-retry",
+ },
+
+ /* Configure projects for major browsers */
+ projects: [
+ {
+ name: "chromium",
+ use: { ...devices["Desktop Chrome"] },
+ },
+
+ // {
+ // name: "firefox",
+ // use: { ...devices["Desktop Firefox"] },
+ // },
+ //
+ // {
+ // name: "webkit",
+ // use: { ...devices["Desktop Safari"] },
+ // },
+
+ /* Test against mobile viewports. */
+ // {
+ // name: "Mobile Chrome",
+ // use: { ...devices["Pixel 5"] },
+ // },
+ // {
+ // name: "Mobile Safari",
+ // use: { ...devices["iPhone 12"] },
+ // },
+
+ /* Test against branded browsers. */
+ // {
+ // name: "Microsoft Edge",
+ // use: { ...devices["Desktop Edge"], channel: "msedge" },
+ // },
+ // {
+ // name: "Google Chrome",
+ // use: { ...devices["Desktop Chrome"], channel: "chrome" },
+ // },
+ ],
+
+ /* Run your local dev server before starting the tests */
+ webServer: {
+ command: "npm run dev",
+ url: "http://127.0.0.1:3000",
+ reuseExistingServer: !process.env.CI,
+ },
+});