Skip to content
Open
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
20 changes: 11 additions & 9 deletions .github/workflows/wrapper_tests_e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -170,20 +170,22 @@ jobs:
- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Start server for ${{ matrix.framework }}
working-directory: e2e/wrappers
run: |
pnpm run start:${{ matrix.framework }} &
sleep 10

- name: Run tests for ${{ matrix.framework }}
working-directory: e2e/wrappers
run: pnpm run test:${{ matrix.framework }}

- name: Upload test artifacts on failure
- name: Upload test report on failure
if: ${{ failure() }}
uses: actions/upload-artifact@v7
with:
name: playwright-report-${{matrix.framework}}
path: e2e/wrappers/playwright-report
if-no-files-found: ignore

- name: Upload test traces on failure
if: ${{ failure() }}
uses: actions/upload-artifact@v7
with:
name: test-fails-${{matrix.framework}}
path: e2e/wrappers/screenshots
name: playwright-traces-${{matrix.framework}}
path: e2e/wrappers/test-results
if-no-files-found: ignore
1 change: 0 additions & 1 deletion apps/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
"webpack-dev-server": "5.2.6"
},
"scripts": {
"test": "node runner.js",
"start": "webpack-dev-server",
"build": "webpack"
},
Expand Down
1 change: 0 additions & 1 deletion apps/react/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
"!{projectRoot}/public/js/app/bundle*",
"{projectRoot}/*.tsx",
"{projectRoot}/*.js",
"!{projectRoot}/test.js",
"{projectRoot}/tsconfig.json",
"{workspaceRoot}/tsconfig.json"
],
Expand Down
17 changes: 0 additions & 17 deletions apps/react/runner.js

This file was deleted.

8 changes: 0 additions & 8 deletions apps/react/test.js

This file was deleted.

1 change: 0 additions & 1 deletion apps/vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
"webpack-dev-server": "5.2.6"
},
"scripts": {
"test": "node runner.js",
"start": "webpack-dev-server",
"build": "webpack"
}
Expand Down
1 change: 0 additions & 1 deletion apps/vue/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
"{projectRoot}/*.ts",
"{projectRoot}/*.vue",
"{projectRoot}/*.js",
"!{projectRoot}/test.js",
"{projectRoot}/tsconfig.json"
],
"outputs": [
Expand Down
17 changes: 0 additions & 17 deletions apps/vue/runner.js

This file was deleted.

8 changes: 0 additions & 8 deletions apps/vue/test.js

This file was deleted.

4 changes: 4 additions & 0 deletions e2e/wrappers/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
playwright-report/
test-results/
ci-report/
ci-traces/
44 changes: 44 additions & 0 deletions e2e/wrappers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Wrappers E2E tests

End-to-end tests that check DevExtreme components inside the React, Vue and Angular wrappers.
They run on [Playwright](https://playwright.dev/) and use the system Google Chrome
(`channel: 'chrome'`), so no browser download is needed.

## Run locally

```bash
pnpm install --frozen-lockfile
pnpm nx all:build-testing workflows

cd e2e/wrappers
pnpm run build:react19 # or build:vue3 / build:angular / build:all
pnpm run test:react19 # or test:vue3 / test:angular
```

`playwright test` starts the server for the built application itself.

## Run in the CI environment

The container takes Node from `.node-version` and Chrome from the version the workflow installs;
dependencies and application builds come from the host.

```bash
docker/run.sh react19
docker/run.sh --ui react19 # then open http://localhost:9323
```

Open the UI on `localhost` — the address Playwright prints, `0.0.0.0`, is not a secure origin and
its trace viewer will not load there.

## Read a failed CI run

```bash
gh run download <run-id> -n playwright-report-react19 -D ci-report
gh run download <run-id> -n playwright-traces-react19 -D ci-traces

pnpm exec playwright show-report ci-report
pnpm exec playwright show-trace ci-traces/<test-name>/trace.zip --port 0
```

The trace holds every action with the DOM before and after it, the network and the console, so a
failure that only happens on CI can be diagnosed without reproducing it.
17 changes: 17 additions & 0 deletions e2e/wrappers/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Mirrors the environment the tests get on CI.
FROM ubuntu:24.04

ARG NODE_VERSION
ARG CHROME_VERSION

RUN echo 'APT::Install-Recommends "0";' > /etc/apt/apt.conf.d/dx-no-recommends \
&& apt-get update \
&& apt-get install -y ca-certificates curl fonts-noto-color-emoji \
&& curl -fsSL "https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_${CHROME_VERSION}-1_amd64.deb" -o /tmp/chrome.deb \
&& apt-get install -y /tmp/chrome.deb \
&& curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz" -o /tmp/node.tar.gz \
&& tar -xzf /tmp/node.tar.gz -C /usr/local --strip-components=1 \
&& rm /tmp/chrome.deb /tmp/node.tar.gz \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /repo/e2e/wrappers
37 changes: 37 additions & 0 deletions e2e/wrappers/docker/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/bash
# Usage: docker/run.sh [--ui] [react19|vue3|angular] [playwright args]

set -euo pipefail

UI_PORT=9323
UI=false

if [ "${1:-}" = "--ui" ]; then
UI=true
shift
fi

FRAMEWORK="${1:-react19}"
shift || true

REPO_ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
NODE_VERSION="$(cat "$REPO_ROOT/.node-version")"
CHROME_VERSION="$(grep -m1 'chrome-version:' "$REPO_ROOT/.github/workflows/wrapper_tests_e2e.yml" | cut -d: -f2 | tr -d " '\"")"

echo "Node $NODE_VERSION, Google Chrome $CHROME_VERSION"

docker build --platform linux/amd64 \
--build-arg "NODE_VERSION=$NODE_VERSION" \
--build-arg "CHROME_VERSION=$CHROME_VERSION" \
-t devextreme-wrappers-e2e "$REPO_ROOT/e2e/wrappers/docker"

RUN=(docker run --rm --platform linux/amd64 --shm-size=2gb --security-opt seccomp=unconfined
-v "$REPO_ROOT:/repo" -w /repo/e2e/wrappers -e "FRAMEWORK=$FRAMEWORK")

if [ "$UI" = true ]; then
echo "UI mode for $FRAMEWORK: open http://localhost:$UI_PORT"
exec "${RUN[@]}" -p "$UI_PORT:$UI_PORT" devextreme-wrappers-e2e \
node_modules/.bin/playwright test --ui-host=0.0.0.0 --ui-port="$UI_PORT" "$@"
fi

exec "${RUN[@]}" -e CI=true devextreme-wrappers-e2e node_modules/.bin/playwright test "$@"
13 changes: 13 additions & 0 deletions e2e/wrappers/fixtures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { test as base } from '@playwright/test';

export type Framework = 'react19' | 'vue3' | 'angular';

export interface TestOptions {
framework: Framework;
}

export const test = base.extend<TestOptions>({
framework: ['react19', { option: true }],
});

export { expect } from '@playwright/test';
10 changes: 5 additions & 5 deletions e2e/wrappers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
"start:vue3": "pnpm run dev:vue3 -- --host",
"start:angular": "cd builders/angular && pnpm run start",
"build:all": "pnpm run build:react19 && pnpm run build:vue3 && pnpm run build:angular",
"test:react19": "node ./runner.js --framework=react",
"test:vue3": "node ./runner.js --framework=vue",
"test:angular": "node ./runner.js --framework=angular"
"test:react19": "cross-env FRAMEWORK=react19 playwright test",
"test:vue3": "cross-env FRAMEWORK=vue3 playwright test",
"test:angular": "cross-env FRAMEWORK=angular playwright test"
},
"dependencies": {
"@angular/common": "catalog:angular",
Expand All @@ -40,7 +40,6 @@
"inferno-create-element": "^8.2.0",
"jszip": "^3.10.1",
"luxon": "3.4.4",
"minimist": "1.2.8",
"react": "^19.2.8",
"react-dom": "^19.2.8",
"react-router": "^8.3.0",
Expand All @@ -59,11 +58,13 @@
"@angular/cli": "catalog:angular",
"@angular/compiler-cli": "catalog:angular",
"@eslint/js": "catalog:",
"@playwright/test": "catalog:",
"@types/jasmine": "5.1.4",
"@types/react": "19.1.2",
"@types/react-dom": "19.1.3",
"@vitejs/plugin-react": "4.7.0",
"@vitejs/plugin-vue": "5.2.4",
"cross-env": "7.0.3",
"eslint": "9.39.4",
"eslint-plugin-react-hooks": "7.0.1",
"eslint-plugin-react-refresh": "0.5.2",
Expand All @@ -74,7 +75,6 @@
"karma-coverage": "2.2.1",
"karma-jasmine": "5.1.0",
"karma-jasmine-html-reporter": "2.1.0",
"testcafe": "catalog:",
"typescript": "5.8.3",
"vite": "8.0.16"
},
Expand Down
50 changes: 50 additions & 0 deletions e2e/wrappers/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { defineConfig } from '@playwright/test';

import type { Framework, TestOptions } from './fixtures';

const FRAMEWORK_PORTS: Record<Framework, number> = {
react19: 3030,
angular: 3031,
vue3: 3032,
};

const framework = (process.env.FRAMEWORK ?? 'react19') as Framework;
const port = FRAMEWORK_PORTS[framework];

if(!port) {
throw new Error(`Unsupported framework: ${framework}. Expected one of: ${Object.keys(FRAMEWORK_PORTS).join(', ')}.`);
}

const baseURL = `http://localhost:${port}`;

export default defineConfig<TestOptions>({
testDir: './tests',
fullyParallel: true,
forbidOnly: !!process.env.CI,
workers: 1,
reporter: process.env.CI
? [['list'], ['html', { open: 'never' }]]
: [['list']],
timeout: 30000,
expect: { timeout: 5000 },
use: {
framework,
baseURL,
channel: 'chrome',
headless: true,
viewport: { width: 1200, height: 800 },
launchOptions: {
args: ['--no-sandbox', '--disable-gpu'],
// Playwright hides scrollbars in headless by default, which changes the page layout.
ignoreDefaultArgs: ['--hide-scrollbars'],
},
trace: 'retain-on-failure',
screenshot: 'only-on-failure',
},
webServer: {
command: `node ./serve.mjs --framework=${framework} --port=${port}`,
url: baseURL,
reuseExistingServer: !process.env.CI,
timeout: 30000,
},
});
Loading
Loading