Skip to content

Commit cb7d7ab

Browse files
committed
First playwright tests
1 parent 7447559 commit cb7d7ab

File tree

13 files changed

+349
-0
lines changed

13 files changed

+349
-0
lines changed

.github/workflows/playwright.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Playwright Tests
2+
on:
3+
push:
4+
branches: [ main, master ]
5+
pull_request:
6+
branches: [ main, master ]
7+
jobs:
8+
test:
9+
timeout-minutes: 60
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
- uses: actions/setup-node@v4
14+
with:
15+
node-version: lts/*
16+
- name: Install dependencies
17+
run: npm ci
18+
- name: Install Playwright Browsers
19+
run: npx playwright install --with-deps
20+
- name: Run Playwright tests
21+
run: npx playwright test
22+
- uses: actions/upload-artifact@v4
23+
if: always()
24+
with:
25+
name: playwright-report
26+
path: playwright-report/
27+
retention-days: 30

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,6 @@ out
2424
npm-debug.log*
2525
yarn-debug.log*
2626
yarn-error.log*
27+
28+
playwright-report/
29+
test-results/

.prettierignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
<<<<<<< Updated upstream
12
projects/src/samples/project_06/04_pong_asm.ts
23
web/public/pico.min.css
4+
=======
5+
simulator/src/projects/project_06/04_pong.ts
6+
simulator/src/projects/project_06/04_pong_asm.ts
7+
>>>>>>> Stashed changes
38
web/src/locales

e2e/README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# NAND2Testris Web IDE e2e Tests
2+
3+
This is a brief cookbook for NAND2Tetris web ide Playwright e2e tests.
4+
5+
All commands should be run from the root folder, not this /e2e folder.
6+
7+
Before running any commands, run the server with `npm start` in a separate terminal.
8+
9+
## Install Playwright dependencies
10+
11+
```
12+
npx playwright install
13+
```
14+
15+
## Run all e2e tests
16+
17+
```
18+
npm run e2e
19+
```
20+
21+
## Only run tests for chip
22+
23+
```
24+
npm run e2e -- chip
25+
```
26+
27+
Replace chip with cpu, asm, vm, etc.
28+
29+
## Only run tests in Chromium
30+
31+
```
32+
npm run e2e -- --project chromium
33+
```
34+
35+
## Debug Tests
36+
37+
Use the Playwright VSCode plugin.
38+
39+
## View Tests
40+
41+
```
42+
npm run e2e -- --ui
43+
```
44+
45+
## More Info
46+
47+
Review the Playwright documentation and e2e folder.

e2e/asm.spec.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { expect } from "@playwright/test";
2+
import { test } from "./util/base.ts";
3+
4+
test.describe("asm", () => {
5+
test("has title", async ({ page }) => {
6+
await page.goto("asm");
7+
8+
await expect(page).toHaveTitle(/NAND2Tetris/);
9+
await expect(page.getByText("Assembler")).toBeVisible();
10+
await expect(page.getByText("Compiled with problems:")).not.toBeAttached();
11+
await expect(page.getByText("Uncaught runtime errors:")).not.toBeAttached();
12+
});
13+
});

e2e/chip.spec.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { expect } from "@playwright/test";
2+
import { test } from "./util/base.ts";
3+
4+
const NOT = `CHIP Not {
5+
IN in;
6+
OUT out;
7+
8+
PARTS:
9+
Nand(a=in, b=in, out=out);
10+
}`;
11+
12+
test.describe("chip", () => {
13+
test("has title", async ({ page }) => {
14+
await page.goto("chip");
15+
16+
await expect(page).toHaveTitle(/NAND2Tetris/);
17+
await expect(page.getByText("Hardware Simulator")).toBeVisible();
18+
await expect(page.getByText("Compiled with problems:")).not.toBeAttached();
19+
await expect(page.getByText("Uncaught runtime errors:")).not.toBeAttached();
20+
});
21+
22+
test("simple chip", async ({ page, monaco }) => {
23+
await page.goto("chip");
24+
await page.getByRole("button", { name: "Accept" }).click();
25+
await page.getByTestId("project-picker").selectOption("Project 1");
26+
await page.getByTestId("chip-picker").selectOption("Not");
27+
28+
await monaco.write(NOT);
29+
await page.screenshot({ path: "not.png" });
30+
await expect(page.getByText("HDL code: No syntax errors")).toBeVisible();
31+
32+
await page.getByRole("button", { name: "Run ️⏩" }).click();
33+
await expect(
34+
page.getByText(
35+
"Simulation successful: The output file is identical to the compare file",
36+
),
37+
).toBeVisible();
38+
});
39+
});

e2e/compiler.spec.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { expect } from "@playwright/test";
2+
import { test } from "./util/base.ts";
3+
4+
test.describe("compiler", () => {
5+
test("has title", async ({ page }) => {
6+
await page.goto("compiler");
7+
8+
await expect(page).toHaveTitle(/NAND2Tetris/);
9+
await expect(page.getByText("Jack Compiler")).toBeVisible();
10+
await expect(page.getByText("Compiled with problems:")).not.toBeAttached();
11+
await expect(page.getByText("Uncaught runtime errors:")).not.toBeAttached();
12+
});
13+
});

e2e/cpu.spec.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { expect } from "@playwright/test";
2+
import { test } from "./util/base.ts";
3+
4+
test.describe("cpu", () => {
5+
test("has title", async ({ page }) => {
6+
await page.goto("cpu");
7+
8+
await expect(page).toHaveTitle(/NAND2Tetris/);
9+
await expect(page.getByText("CPU Emulator")).toBeVisible();
10+
await expect(page.getByText("Compiled with problems:")).not.toBeAttached();
11+
await expect(page.getByText("Uncaught runtime errors:")).not.toBeAttached();
12+
});
13+
});

e2e/util/base.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import type { Locator, Page } from "@playwright/test";
2+
import { test as base } from "@playwright/test";
3+
4+
export class MonacoPage {
5+
public readonly monacoEditor: Locator;
6+
constructor(readonly page: Page) {
7+
this.monacoEditor = page.locator(".monaco-editor").nth(0);
8+
}
9+
10+
async clearEditor() {
11+
await this.monacoEditor.click();
12+
await this.page.keyboard.press("ControlOrMeta+KeyA");
13+
await this.page.keyboard.press("Backspace");
14+
await this.page.keyboard.press("ControlOrMeta+KeyA");
15+
await this.page.keyboard.press("Backspace");
16+
}
17+
18+
async write(text: string) {
19+
await this.clearEditor();
20+
await this.monacoEditor.click();
21+
for (const line of text.split("\n")) {
22+
await this.page.keyboard.type(`${line}\n`);
23+
}
24+
}
25+
}
26+
27+
export const test = base.extend<{ monaco: MonacoPage }>({
28+
monaco: async ({ page }, use) => {
29+
const monaco = new MonacoPage(page);
30+
await use(monaco);
31+
},
32+
});

e2e/vm.spec.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { expect } from "@playwright/test";
2+
import { test } from "./util/base.ts";
3+
4+
test.describe("vm", () => {
5+
test("has title", async ({ page }) => {
6+
await page.goto("vm");
7+
8+
await expect(page).toHaveTitle(/NAND2Tetris/);
9+
await expect(page.getByText("VM Emulator")).toBeVisible();
10+
await expect(page.getByText("Compiled with problems:")).not.toBeAttached();
11+
await expect(page.getByText("Uncaught runtime errors:")).not.toBeAttached();
12+
});
13+
});

0 commit comments

Comments
 (0)