Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: refactor e2e tests to run with Vitest #762

Closed
wants to merge 4 commits into from
Closed
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
25 changes: 3 additions & 22 deletions .github/workflows/test-app-e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,11 @@ jobs:
matrix:
node-version: [18.x]
os: [ubuntu-20.04, macos-11, windows-2022]
group: [0, 1, 2]
include:
- node-version: 14
os: ubuntu-latest
group: 0
- node-version: 14
os: ubuntu-latest
group: 1
- node-version: 14
os: ubuntu-latest
group: 2
- node-version: 16
os: ubuntu-latest
group: 0
- node-version: 16
os: ubuntu-latest
group: 1
- node-version: 16
os: ubuntu-latest
group: 2
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
Expand All @@ -70,22 +55,19 @@ jobs:
- run: pnpm turbo run build --scope="@previewjs/e2e-test-runner" --include-dependencies
- run: pnpm install # necessary to link e2e-test-runner
- run: pnpm turbo run e2e-test --scope="@previewjs/app" --include-dependencies
env:
GROUP_INDEX: ${{ matrix.group }}
GROUP_COUNT: 3
- name: Archive success screenshots
if: ${{ always() }}
uses: actions/upload-artifact@v3
with:
name: success-screenshots-${{ runner.os }}-${{ matrix.node-version }}-${{ matrix.group }}
name: success-screenshots-${{ runner.os }}-${{ matrix.node-version }}
path: |
app/tests/__screenshots__
pro/tests/__screenshots__
- name: Archive failure screenshots
if: ${{ failure() }}
uses: actions/upload-artifact@v3
with:
name: failure-screenshots-${{ runner.os }}-${{ matrix.node-version }}-${{ matrix.group }}
name: failure-screenshots-${{ runner.os }}-${{ matrix.node-version }}
path: |
app/tests/__failures__
pro/tests/__failures__
Expand Down Expand Up @@ -121,15 +103,14 @@ jobs:
env:
MATRIX_NODE_VERSION: ${{ matrix.node-version }}
MATRIX_OS: ${{ matrix.os }}
MATRIX_GROUP: ${{ matrix.group }}
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `⚠️ Screenshots have changed: group ${process.env.MATRIX_GROUP}, ${process.env.MATRIX_OS} (Node ${process.env.MATRIX_NODE_VERSION})`
body: `⚠️ Screenshots have changed: ${process.env.MATRIX_OS} (Node ${process.env.MATRIX_NODE_VERSION})`
})
- name: Fail if screenshots have changed on main branch
run: git diff --exit-code
Expand Down
7 changes: 4 additions & 3 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@
},
"scripts": {
"prepublish": "cd .. && pnpm turbo run build --scope=@previewjs/app --no-deps --include-dependencies",
"build": "unbuild && pnpm tsc -p client/tsconfig.json && vite build client && pnpm tsc -p tsconfig.tests.json",
"build": "unbuild && pnpm tsc -p client/tsconfig.json && vite build client",
"client:dev": "vite client",
"e2e-test": "tsc && pnpm previewjs-e2e-test -s ./dist/src/index.js -t ./dist/tests/index.js"
"e2e-test": "vitest"
},
"dependencies": {
"express": "^4.18.1"
Expand Down Expand Up @@ -58,6 +58,7 @@
"typescript": "4.7.4",
"unbuild": "0.7.4",
"vite": "2.9.13",
"vite-plugin-svgr": "2.2.0"
"vite-plugin-svgr": "2.2.0",
"vitest": "0.17.0"
}
}
3 changes: 3 additions & 0 deletions app/src/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import type { SetupPreviewEnvironment } from "@previewjs/core";
declare const setup: SetupPreviewEnvironment;
export default setup;
27 changes: 27 additions & 0 deletions app/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = __importDefault(require("express"));
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const setup = async () => {
return {
middlewares: [express_1.default.static(findClientDir(__dirname))],
};
};
function findClientDir(dirPath) {
const potentialPath = path_1.default.join(dirPath, "client", "dist");
if (fs_1.default.existsSync(potentialPath)) {
return potentialPath;
}
else {
const parentPath = path_1.default.dirname(dirPath);
if (!parentPath || parentPath === dirPath) {
throw new Error(`Unable to find compiled client directory (client/dist)`);
}
return findClientDir(parentPath);
}
}
exports.default = setup;
13 changes: 0 additions & 13 deletions app/tests/index.ts

This file was deleted.

198 changes: 95 additions & 103 deletions app/tests/react/action-logs.spec.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,47 @@
import { testSuite } from "@previewjs/e2e-test-runner";
import reactPlugin from "@previewjs/plugin-react";
import { describe, it } from "vitest";

export const actionLogsTests = testSuite(
[reactPlugin],
"react/action logs",
(test) => {
for (const version of [16, 17, 18]) {
test(
`${version}/shows action logs with fn() callback`,
`react${version}`,
async ({ appDir, controller }) => {
await appDir.update("src/Button.tsx", {
kind: "replace",
text: `
function Button(props: { label: string; onClick(): void }) {
return (
<button id="button" onClick={props.onClick}>
{props.label}
</button>
);
}
`,
});
await controller.show("src/Button.tsx:Button");
await controller.props.editor.replaceText(`
properties = {
onClick: fn("onClick")
};
`);
const previewIframe = await controller.previewIframe();
await previewIframe.waitForSelector("#button");
await previewIframe.click("#button");
const actionLog = await controller.actionLog.get(
"Function prop invoked: onClick"
);
await actionLog.waitUntilVisible();
await actionLog.waitUntilGone();
}
describe("react/action logs", () => {
for (const version of [16, 17, 18]) {
it("shows action logs with fn() callback", async (ctx) => {
const { appDir, controller } = await ctx.setupTest(`react${version}`, [
reactPlugin,
]);
await appDir.update("src/Button.tsx", {
kind: "replace",
text: `
function Button(props: { label: string; onClick(): void }) {
return (
<button id="button" onClick={props.onClick}>
{props.label}
</button>
);
}
`,
});
await controller.show("src/Button.tsx:Button");
await controller.props.editor.replaceText(`
properties = {
onClick: fn("onClick")
};
`);
const previewIframe = await controller.previewIframe();
await previewIframe.waitForSelector("#button");
await previewIframe.click("#button");
const actionLog = await controller.actionLog.get(
"Function prop invoked: onClick"
);
await actionLog.waitUntilVisible();
await actionLog.waitUntilGone();
});

test(
`${version}/shows action logs on autogenerated callback prop`,
`react${version}`,
async ({ appDir, controller }) => {
await appDir.update("src/Button.tsx", {
kind: "replace",
text: `
it("shows action logs on autogenerated callback prop", async (ctx) => {
const { appDir, controller } = await ctx.setupTest(`react${version}`, [
reactPlugin,
]);
await appDir.update("src/Button.tsx", {
kind: "replace",
text: `
function Button(props: { label: string; onClick(): void }) {
return (
<button id="button" onClick={props.onClick}>
Expand All @@ -54,26 +50,25 @@ function Button(props: { label: string; onClick(): void }) {
);
}
`,
});
await controller.show("src/Button.tsx:Button");
const previewIframe = await controller.previewIframe();
await previewIframe.waitForSelector("#button");
await previewIframe.click("#button");
const actionLog = await controller.actionLog.get(
"Function prop invoked: onClick"
);
await actionLog.waitUntilVisible();
await actionLog.waitUntilGone();
}
});
await controller.show("src/Button.tsx:Button");
const previewIframe = await controller.previewIframe();
await previewIframe.waitForSelector("#button");
await previewIframe.click("#button");
const actionLog = await controller.actionLog.get(
"Function prop invoked: onClick"
);
await actionLog.waitUntilVisible();
await actionLog.waitUntilGone();
});

test(
`${version}/bundles multiple action logs`,
`react${version}`,
async ({ appDir, controller }) => {
await appDir.update("src/Button.tsx", {
kind: "replace",
text: `
it("bundles multiple action logs", async (ctx) => {
const { appDir, controller } = await ctx.setupTest(`react${version}`, [
reactPlugin,
]);
await appDir.update("src/Button.tsx", {
kind: "replace",
text: `
function Button(props: { label: string; a(): void; b(): void; }) {
return (
<>
Expand All @@ -87,41 +82,40 @@ function Button(props: { label: string; a(): void; b(): void; }) {
);
}
`,
});
await controller.show("src/Button.tsx:Button");
await controller.props.editor.replaceText(`
});
await controller.show("src/Button.tsx:Button");
await controller.props.editor.replaceText(`
properties = {
a: fn("a"),
b: fn("b")
};
`);
const previewIframe = await controller.previewIframe();
await previewIframe.waitForSelector("#a");
await previewIframe.click("#a");
await previewIframe.click("#a");
await previewIframe.click("#a");
await previewIframe.click("#b");
await previewIframe.click("#b");
const actionLogA = await controller.actionLog.get(
"Function prop invoked: a (x3)"
);
const actionLogB = await controller.actionLog.get(
"Function prop invoked: b (x2)"
);
await actionLogA.waitUntilVisible();
await actionLogB.waitUntilVisible();
await actionLogA.waitUntilGone();
await actionLogB.waitUntilGone();
}
const previewIframe = await controller.previewIframe();
await previewIframe.waitForSelector("#a");
await previewIframe.click("#a");
await previewIframe.click("#a");
await previewIframe.click("#a");
await previewIframe.click("#b");
await previewIframe.click("#b");
const actionLogA = await controller.actionLog.get(
"Function prop invoked: a (x3)"
);
const actionLogB = await controller.actionLog.get(
"Function prop invoked: b (x2)"
);
await actionLogA.waitUntilVisible();
await actionLogB.waitUntilVisible();
await actionLogA.waitUntilGone();
await actionLogB.waitUntilGone();
});

test(
`${version}/shows action logs on link click`,
`react${version}`,
async ({ appDir, controller }) => {
await appDir.update("src/Link.tsx", {
kind: "replace",
text: `
it("shows action logs on link click", async (ctx) => {
const { appDir, controller } = await ctx.setupTest(`react${version}`, [
reactPlugin,
]);
await appDir.update("src/Link.tsx", {
kind: "replace",
text: `
function Link() {
return (
<a id="link" href="https://www.google.com">
Expand All @@ -130,18 +124,16 @@ function Link() {
);
}
`,
});
await controller.show("src/Link.tsx:Link");
const previewIframe = await controller.previewIframe();
await previewIframe.waitForSelector("#link");
await previewIframe.click("#link");
const actionLog = await controller.actionLog.get(
"Redirect prevented: https://www.google.com"
);
await actionLog.waitUntilVisible();
await actionLog.waitUntilGone();
}
});
await controller.show("src/Link.tsx:Link");
const previewIframe = await controller.previewIframe();
await previewIframe.waitForSelector("#link");
await previewIframe.click("#link");
const actionLog = await controller.actionLog.get(
"Redirect prevented: https://www.google.com"
);
}
await actionLog.waitUntilVisible();
await actionLog.waitUntilGone();
});
}
);
});
Loading