Webdriver.io (#588)

* add webdriver tests

* reduce build time for test

---------

Co-authored-by: neil molina <neil@neils-MacBook-Pro.local>
This commit is contained in:
ABevier 2023-05-11 22:56:45 -04:00 committed by GitHub
parent 4d95bb89ee
commit c76473cf16
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 1977 additions and 19 deletions

View file

@ -49,7 +49,7 @@ jobs:
steps: steps:
- uses: teaxyz/setup@v0 - uses: teaxyz/setup@v0
with: with:
version: 0.26.2 version: 0.31.2
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: env file - name: env file
run: cp modules/desktop/.env.example modules/desktop/.env run: cp modules/desktop/.env.example modules/desktop/.env
@ -62,15 +62,39 @@ jobs:
# run: pnpm --filter desktop run coverage # run: pnpm --filter desktop run coverage
- name: lint - name: lint
run: tea -E pnpm -r lint run: tea -E pnpm -r lint
- name: chec - name: check
run: tea -E pnpm -r check run: tea -E pnpm -r check
e2e_test:
needs: changes
runs-on: macos-latest
env:
# see: https://github.com/electron-userland/electron-builder/issues/3179
USE_HARD_LINKS: false
steps:
- uses: teaxyz/setup@v0
with:
version: 0.31.2
- uses: actions/checkout@v3
- name: env file
run: cp modules/desktop/.env.example modules/desktop/.env
- name: install app dependencies
run: tea -E xc setup
- name: test build electron main process
run: tea -E xc build
env:
CSC_IDENTITY_AUTO_DISCOVERY: "false"
MAC_BUILD_TARGET: "dir"
- name: e2e test
run: tea -E xc e2e
build_svelte: build_svelte:
needs: changes needs: changes
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: teaxyz/setup@v0 - uses: teaxyz/setup@v0
with: with:
version: 0.26.2 version: 0.31.2
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: cache node_modules build - name: cache node_modules build
# TODO: cache issue in our self-hosted macos runner ESPIPE: invalid seek, read # TODO: cache issue in our self-hosted macos runner ESPIPE: invalid seek, read

View file

@ -109,6 +109,14 @@ pnpm run -r check
pnpm run -r lint pnpm run -r lint
``` ```
## e2e
Runs the webdriver.io end to end tests. Assumes that `xc build` has already been executed.
```sh
pnpm run --reporter append-only -r e2e
```
## Bump ## Bump
Inputs: PRIORITY Inputs: PRIORITY

View file

@ -17,7 +17,7 @@ module.exports = {
mac: { mac: {
icon: "./electron/icon.icns", icon: "./electron/icon.icns",
target: { target: {
target: "default", target: process.env.MAC_BUILD_TARGET || "default",
arch: ["x64", "arm64"] arch: ["x64", "arm64"]
}, },
minimumSystemVersion: "11" minimumSystemVersion: "11"

View file

@ -28,7 +28,8 @@
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --compiler-warnings \"css-unused-selector:ignore\"", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --compiler-warnings \"css-unused-selector:ignore\"",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --compiler-warnings \"css-unused-selector:ignore\" --watch", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --compiler-warnings \"css-unused-selector:ignore\" --watch",
"lint": "prettier --check . && eslint .", "lint": "prettier --check . && eslint .",
"format": "prettier --write ." "format": "prettier --write .",
"e2e": "wdio run ./wdio.conf.ts"
}, },
"devDependencies": { "devDependencies": {
"@electron/notarize": "^1.2.3", "@electron/notarize": "^1.2.3",
@ -42,12 +43,18 @@
"@tea/ui": "workspace:*", "@tea/ui": "workspace:*",
"@testing-library/jest-dom": "^5.16.5", "@testing-library/jest-dom": "^5.16.5",
"@testing-library/svelte": "^3.2.2", "@testing-library/svelte": "^3.2.2",
"@testing-library/webdriverio": "^3.2.1",
"@types/bcryptjs": "^2.4.2", "@types/bcryptjs": "^2.4.2",
"@types/js-yaml": "^4.0.5", "@types/js-yaml": "^4.0.5",
"@types/mixpanel-browser": "^2.38.1", "@types/mixpanel-browser": "^2.38.1",
"@types/testing-library__jest-dom": "^5.14.5", "@types/testing-library__jest-dom": "^5.14.5",
"@typescript-eslint/eslint-plugin": "^5.27.0", "@typescript-eslint/eslint-plugin": "^5.27.0",
"@typescript-eslint/parser": "^5.27.0", "@typescript-eslint/parser": "^5.27.0",
"@wdio/cli": "^8.10.1",
"@wdio/globals": "^8.10.1",
"@wdio/local-runner": "^8.10.1",
"@wdio/mocha-framework": "^8.10.1",
"@wdio/spec-reporter": "^8.10.1",
"autoprefixer": "^10.4.13", "autoprefixer": "^10.4.13",
"concurrently": "^7.6.0", "concurrently": "^7.6.0",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
@ -67,10 +74,12 @@
"svelte-preprocess": "^5.0.1", "svelte-preprocess": "^5.0.1",
"svelte2tsx": "^0.5.20", "svelte2tsx": "^0.5.20",
"tailwindcss": "^3.2.4", "tailwindcss": "^3.2.4",
"ts-node": "^10.9.1",
"tslib": "^2.3.1", "tslib": "^2.3.1",
"typescript": "^4.7.4", "typescript": "^4.7.4",
"vite": "^4.1.1", "vite": "^4.1.1",
"vitest": "^0.28.3" "vitest": "^0.28.3",
"wdio-electron-service": "^4.0.2"
}, },
"type": "module", "type": "module",
"dependencies": { "dependencies": {

View file

@ -91,7 +91,9 @@
</figure> </figure>
<article class="w-2/3 p-4 pt-8"> <article class="w-2/3 p-4 pt-8">
<div class="align-center flex items-center gap-2"> <div class="align-center flex items-center gap-2">
<h3 class="text-3xl text-primary">{fixPackageName(pkg.name)}</h3> <h3 data-testid="package-banner-header" class="text-3xl text-primary">
{fixPackageName(pkg.name)}
</h3>
<ButtonIcon <ButtonIcon
icon="pencil" icon="pencil"
helpText="edit package" helpText="edit package"

View file

@ -30,7 +30,10 @@
<BgImage class="absolute left-0 top-0 h-full w-full" {layout} {pkg} /> <BgImage class="absolute left-0 top-0 h-full w-full" {layout} {pkg} />
<a href={link} on:mousedown={activate} on:mouseup={deactivate} on:mouseleave={deactivate}> <a href={link} on:mousedown={activate} on:mouseup={deactivate} on:mouseleave={deactivate}>
<div class="package-card-content absolute h-full w-full flex-col justify-between"> <div
data-testid={`package-card-${pkg.slug}`}
class="package-card-content absolute h-full w-full flex-col justify-between"
>
<div class="hint-container"> <div class="hint-container">
<div class="hint"> <div class="hint">
<div class="text-xs line-clamp-1">view more details</div> <div class="text-xs line-clamp-1">view more details</div>

View file

@ -0,0 +1,37 @@
import { browser } from "wdio-electron-service";
import { setupUtils } from "./utils.ts";
describe("basic smoke test", () => {
it("install brewkit from the made by tea tab", async () => {
const utils = setupUtils(browser);
const { screen } = utils!;
// app launches to discover screen by default - make sure Stable Diffusion is there
await expect(await screen.findByText("Stable Diffusion web UI")).toExist();
// navigate to "made by tea" page
const btn = await utils.findButton("made by tea");
btn.click();
// find the brewkit package
const pkgCard = await utils.findPackageCardBySlug("tea_xyz_brewkit");
pkgCard.click();
await utils.packageDetailsLoaded();
// Be nice to devs running this over and over
await utils.uninstallPackageIfNeeded();
await utils.installLatestVersion();
//use findByText to wait for the install to complete
await expect(
await screen.findByText(
/^Package tea.xyz\/brewkit .* has been installed./,
{},
{ timeout: 60000, interval: 1000 }
)
).toExist();
await expect(await screen.findByRole("button", { name: "OPEN IN TERMINAL" })).toExist();
});
});

View file

@ -0,0 +1,62 @@
import testingLibraryWdio from "@testing-library/webdriverio";
// work around for importing CommonJS module
const { setupBrowser } = testingLibraryWdio;
//TODO: This should probably evolve into a "page object" pattern, but for now it's just a pile of utils
export function setupUtils(browser: WebdriverIO.Browser) {
const screen = setupBrowser(browser as any);
const findButton = async (name: RegExp | string) => {
return (await screen.findByRole("button", { name })) as unknown as HTMLElement;
};
//
// Package List Page
//
// Find a package card on a package list screen
const findPackageCardBySlug = async (slug: string) => {
// Trying to find the anchor tag role doesn't work, so we have to find by test id of the div inside the anchor
return (await screen.findByTestId(`package-card-${slug}`)) as unknown as HTMLElement;
};
//
// Package Details Page
//
const packageDetailsLoaded = async () => {
// try to find the package banner header so we know the page is at least mostly loaded
await screen.findByTestId("package-banner-header", {}, { timeout: 10000, interval: 500 });
};
const uninstallPackageIfNeeded = async () => {
const uninstallButton = (await screen.queryByRole("button", {
name: "UNINSTALL"
})) as unknown as HTMLElement;
if (uninstallButton) {
uninstallButton.click();
// wait for the install button to show back up
await screen.findByRole("button", { name: /^INSTALL / }, { timeout: 60000, interval: 1000 });
}
};
const installLatestVersion = async () => {
const installButton = await findButton(/^INSTALL |^UPDATE/);
installButton.click();
// install the latest version
const versionInstallButton = (await screen.findByText(/(latest)/)) as unknown as HTMLElement;
versionInstallButton.click();
};
return {
screen,
findButton,
findPackageCardBySlug,
packageDetailsLoaded,
uninstallPackageIfNeeded,
installLatestVersion
};
}
export const sleep = (delayMs: number) => new Promise((resolve) => setTimeout(resolve, delayMs));

View file

@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"allowImportingTsExtensions": true,
"lib": ["dom"],
"strict": true,
"types": ["vitest/globals", "@testing-library/jest-dom", "node", "mocha", "@wdio/globals/types"]
}
}

View file

@ -0,0 +1,57 @@
import type { Options } from "@wdio/types";
import { join } from "path";
import { getDirname } from "cross-dirname";
const dirname = getDirname();
const productName = "tea";
process.env.TEST = "true";
export const config: Options.Testrunner = {
runner: "local",
autoCompileOpts: {
autoCompile: true,
tsNodeOpts: {
project: "./test/tsconfig.json",
transpileOnly: true
}
},
specs: ["./test/specs/**/*.ts"],
exclude: [
// 'path/to/excluded/files'
],
maxInstances: 10,
capabilities: [
{
// capabilities for local browser web tests
browserName: "chrome" // or "firefox", "microsoftedge", "safari"
}
],
logLevel: "debug",
bail: 0,
baseUrl: "http://localhost",
waitforTimeout: 10000,
connectionRetryTimeout: 120000,
connectionRetryCount: 3,
services: [
[
"electron",
{
appPath: join(dirname, "dist"),
appName: productName,
appArgs: [],
chromedriver: {
port: 9519,
logFileName: "wdio-chromedriver.log"
},
electronVersion: "22.1.0"
}
]
],
framework: "mocha",
reporters: ["spec"],
mochaOpts: {
ui: "bdd",
timeout: 60000
}
};

File diff suppressed because it is too large Load diff