diff --git a/.gitignore b/.gitignore index 4f25255d..d745fb8d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,10 @@ /.hermit/ +/e2e/test-results /firebase/*.log /firebase/.firebase/ /frontend/evy.wasm /frontend/version.json /frontend/wasm_exec.js /out/ + +node_modules/ diff --git a/Makefile b/Makefile index 540b3cbc..8d9815a9 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ all: build test lint tiny test-tiny check-coverage sh-lint check-prettier check- @if [ -e .git/rebase-merge ]; then git --no-pager log -1 --pretty='%h %s'; fi @echo '$(COLOUR_GREEN)Success$(COLOUR_NORMAL)' -ci: clean check-uptodate all ## Full clean build and up-to-date checks as run on CI +ci: clean check-uptodate all e2e ## Full clean build and up-to-date checks as run on CI check-uptodate: tidy fmt doc test -z "$$(git status --porcelain)" || { git status; false; } @@ -127,6 +127,10 @@ godoc: install # --- frontend ----------------------------------------------------------------- NODEPREFIX = .hermit/node NODELIB = $(NODEPREFIX)/lib +# TODO: BASEURL should be calculated dynamically for CI/PR. +# BASEURL needs to be in the environment so that `e2e/playwright.config.js` +# can see it when the `e2e` target is called. +export BASEURL = https://evy.dev ## Serve frontend on free port serve: @@ -140,10 +144,16 @@ prettier: | $(NODELIB) check-prettier: | $(NODELIB) npx --prefix $(NODEPREFIX) -y prettier --check . +e2e: + @echo "testing $(BASEURL)" + npm --prefix e2e ci + npx --prefix e2e playwright install --with-deps chromium + npx --prefix e2e playwright test --config e2e + $(NODELIB): @mkdir -p $@ -.PHONY: check-prettier prettier serve +.PHONY: check-prettier e2e prettier serve # --- deploy ----------------------------------------------------------------- diff --git a/e2e/index.test.js b/e2e/index.test.js new file mode 100644 index 00000000..0971d811 --- /dev/null +++ b/e2e/index.test.js @@ -0,0 +1,15 @@ +const { test, expect } = require("@playwright/test") + +test("title", async ({ page, baseURL }) => { + await page.goto(baseURL) + await expect(page).toHaveTitle("evy | Playground") +}) + +test("console output", async ({ page, baseURL }) => { + await page.goto(baseURL) + await page.waitForLoadState("networkidle") + await page.getByRole("button", { name: "Run" }).click() + const console = page.locator("css=#console") + await expect(console).toContainText("x: 12") + await expect(console).toContainText("🍦 big x") +}) diff --git a/e2e/package-lock.json b/e2e/package-lock.json new file mode 100644 index 00000000..20008c63 --- /dev/null +++ b/e2e/package-lock.json @@ -0,0 +1,72 @@ +{ + "name": "e2e", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "devDependencies": { + "@playwright/test": "^1.40.1", + "playwright": "^1.40.1" + } + }, + "node_modules/@playwright/test": { + "version": "1.40.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.40.1.tgz", + "integrity": "sha512-EaaawMTOeEItCRvfmkI9v6rBkF1svM8wjl/YPRrg2N2Wmp+4qJYkWtJsbew1szfKKDm6fPLy4YAanBhIlf9dWw==", + "dev": true, + "dependencies": { + "playwright": "1.40.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/playwright": { + "version": "1.40.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.40.1.tgz", + "integrity": "sha512-2eHI7IioIpQ0bS1Ovg/HszsN/XKNwEG1kbzSDDmADpclKc7CyqkHw7Mg2JCz/bbCxg25QUPcjksoMW7JcIFQmw==", + "dev": true, + "dependencies": { + "playwright-core": "1.40.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.40.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.40.1.tgz", + "integrity": "sha512-+hkOycxPiV534c4HhpfX6yrlawqVUzITRKwHAmYfmsVreltEl6fAZJ3DPfLMOODw0H3s1Itd6MDCWmP1fl/QvQ==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=16" + } + } + } +} diff --git a/e2e/package.json b/e2e/package.json new file mode 100644 index 00000000..b1f8b3ef --- /dev/null +++ b/e2e/package.json @@ -0,0 +1,7 @@ +{ + "private": "true", + "devDependencies": { + "@playwright/test": "^1.40.1", + "playwright": "^1.40.1" + } +} diff --git a/e2e/playwright.config.js b/e2e/playwright.config.js new file mode 100644 index 00000000..a5aeedcb --- /dev/null +++ b/e2e/playwright.config.js @@ -0,0 +1,6 @@ +const { defineConfig, devices } = require("@playwright/test") +module.exports = defineConfig({ + use: { + baseURL: process.env.BASEURL || "http://localhost:8080", + }, +})