Ver código fonte

NO-JIRA: Playwright migration

logonoff 4 meses atrás
pai
commit
2dc6c3bb5e

+ 2 - 2
.gitignore

@@ -2,8 +2,8 @@
 **/dist
 **/.DS_Store
 .devcontainer/dev.env
-integration-tests/videos
-integration-tests/screenshots
+integration-tests/.auth
+integration-tests/results
 
 # Jest
 coverage/

+ 9 - 8
AGENTS.md

@@ -16,7 +16,7 @@ This is a **template repository** for creating OpenShift Console dynamic plugins
 - PatternFly 6 (UI component library)
 - Webpack 5 with Module Federation
 - react-i18next for internationalization
-- Cypress for e2e testing
+- Playwright for e2e testing
 - Helm for deployment
 
 **Compatibility:** Requires OpenShift 4.12+ (uses ConsolePlugin CRD v1 API)
@@ -81,7 +81,7 @@ tsconfig.json          # TypeScript config (strict: false currently)
 webpack.config.ts      # Module federation + build config
 locales/               # i18n translation files
 charts/                # Helm chart for deployment
-integration-tests/     # Cypress e2e tests
+integration-tests/     # Playwright e2e tests
 ```
 
 ## Development Workflow
@@ -98,8 +98,9 @@ integration-tests/     # Cypress e2e tests
 - Follow existing code patterns in the repo
 
 ### Testing
-- `yarn test-cypress` - opens Cypress UI
-- `yarn test-cypress-headless` - runs Cypress in CI mode
+- `yarn test` - runs Jest unit tests
+- `yarn test-e2e` - opens Playwright in headed mode
+- `yarn test-e2e-headless` - runs Playwright in headless mode
 - Add e2e tests for new pages/features
 
 ## TypeScript Configuration
@@ -200,9 +201,9 @@ See [Console Plugin SDK README](https://github.com/openshift/console/tree/master
 
 ## Testing Strategy
 
-- **E2E tests (Cypress):** For user flows and page rendering
-- **Component tests:** Add when components have complex logic
-- **Test data attributes:** Use `data-test` attributes for selectors
+- **E2E tests (Playwright):** For user flows and page rendering
+- **Unit tests (Jest):** For component logic and plugin metadata
+- **Test data attributes:** Use `data-test` attributes for selectors (`testIdAttribute` is configured in `playwright.config.ts`)
 - Run tests locally before opening PRs
 
 ## References
@@ -219,5 +220,5 @@ See [Console Plugin SDK README](https://github.com/openshift/console/tree/master
 - **Add a page?** Update console-extensions.json + exposedModules + create component
 - **Style something?** Use PatternFly components and CSS variables, prefix custom classes
 - **Add translations?** Use `t()` function, run `yarn i18n` after
-- **Test changes?** Run locally with `yarn start` + `yarn start-console`, add Cypress tests
+- **Test changes?** Run locally with `yarn start` + `yarn start-console`, add Playwright tests
 - **Deploy?** Build image, push to registry, install via Helm chart

+ 1 - 1
Dockerfile

@@ -1,7 +1,7 @@
 FROM registry.access.redhat.com/ubi9/nodejs-22:latest AS build
 USER root
 
-ENV CYPRESS_INSTALL_BINARY=0
+ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
 
 ADD . /usr/src/app
 WORKDIR /usr/src/app

+ 0 - 8
README.md

@@ -215,14 +215,6 @@ best practice is to prefix your CSS class names with your plugin name to avoid
 conflicts. Please don't disable these rules without understanding how they can
 break console styles!
 
-## Reporting
-
-Steps to generate reports
-
-1. In command prompt, navigate to root folder and execute the command `yarn run cypress-merge`
-2. Then execute command `yarn run cypress-generate`
-The cypress-report.html file is generated and should be in (/integration-tests/screenshots) directory.
-
 ## References
 
 - [Console Plugin SDK README](https://github.com/openshift/console/tree/main/frontend/packages/console-dynamic-plugin-sdk)

+ 4 - 13
eslint.config.mjs

@@ -5,7 +5,7 @@ import prettier from 'eslint-plugin-prettier/recommended';
 import reactHooks from 'eslint-plugin-react-hooks';
 import importX from 'eslint-plugin-import-x';
 import { createTypeScriptImportResolver } from 'eslint-import-resolver-typescript';
-import cypress from 'eslint-plugin-cypress';
+import playwright from 'eslint-plugin-playwright';
 import jest from 'eslint-plugin-jest';
 import testingLibrary from 'eslint-plugin-testing-library';
 import globals from 'globals';
@@ -72,22 +72,13 @@ export default tseslint.config(
     },
   },
   {
-    files: ['integration-tests/**/*.{ts,tsx,js}'],
+    ...playwright.configs['flat/recommended'],
+    files: ['integration-tests/**/*.ts'],
     ...tseslint.configs.disableTypeChecked,
-    ...cypress.configs.recommended,
-    languageOptions: {
-      globals: {
-        require: 'readonly',
-        module: 'writable',
-      },
-    },
     rules: {
+      ...playwright.configs['flat/recommended'].rules,
       ...tseslint.configs.disableTypeChecked.rules,
-      ...cypress.configs.recommended.rules,
       'no-console': 'off',
-      '@typescript-eslint/no-namespace': 'off',
-      '@typescript-eslint/no-require-imports': 'off',
-      '@typescript-eslint/no-unused-expressions': 'off',
     },
   },
   prettier,

+ 0 - 28
integration-tests/cypress.config.js

@@ -1,28 +0,0 @@
-const { defineConfig } = require('cypress');
-
-module.exports = defineConfig({
-  viewportWidth: 1920,
-  viewportHeight: 1080,
-  screenshotsFolder: './screenshots/screenshots',
-  videosFolder: './screenshots/videos',
-  video: true,
-  reporter: '../../node_modules/cypress-multi-reporters',
-  reporterOptions: {
-    configFile: 'reporter-config.json',
-  },
-  fixturesFolder: 'fixtures',
-  defaultCommandTimeout: 30000,
-  retries: {
-    runMode: 1,
-    openMode: 0,
-  },
-  e2e: {
-    setupNodeEvents(on, config) {
-      return require('./plugins/index.ts')(on, config);
-    },
-    specPattern: 'tests/**/*.cy.{js,jsx,ts,tsx}',
-    supportFile: 'support/index.ts',
-    testIsolation: false,
-    injectDocumentDomain: true,
-  },
-});

+ 0 - 5
integration-tests/fixtures/example.json

@@ -1,5 +0,0 @@
-{
-  "name": "Using fixtures to represent data",
-  "email": "hello@cypress.io",
-  "body": "Fixtures are a great way to mock data for responses to routes"
-}

+ 62 - 0
integration-tests/pages/login.ts

@@ -0,0 +1,62 @@
+import type { Locator, Page } from '@playwright/test';
+
+declare global {
+  interface Window {
+    SERVER_FLAGS?: {
+      authDisabled?: boolean;
+    };
+  }
+}
+
+export const KUBEADMIN_USERNAME = 'kubeadmin';
+
+export class LoginPage {
+  constructor(private readonly page: Page) {}
+
+  private async isAuthDisabled() {
+    return this.page.evaluate(() => window.SERVER_FLAGS?.authDisabled);
+  }
+
+  // Fill a field via CDP to avoid exposing the value in Playwright traces
+  // https://github.com/microsoft/playwright/issues/19992#issuecomment-4078945450
+  private async fillSensitive(locator: Locator, text: string) {
+    await locator.focus();
+    const cdpSession = await this.page.context().newCDPSession(this.page);
+    await cdpSession.send('Input.dispatchKeyEvent', {
+      type: 'keyDown',
+      key: 'a',
+      commands: ['selectAll'],
+    });
+    await cdpSession.send('Input.dispatchKeyEvent', { type: 'keyUp', key: 'a' });
+    await cdpSession.send('Input.insertText', { text });
+    await cdpSession.detach();
+  }
+
+  async login(
+    username: string = KUBEADMIN_USERNAME,
+    password: string = process.env.BRIDGE_KUBEADMIN_PASSWORD ?? '',
+  ) {
+    await this.page.context().clearCookies();
+    await this.page.goto('/');
+
+    if (await this.isAuthDisabled()) {
+      return;
+    }
+
+    await this.page.locator('[data-test-id="login"]').waitFor({ state: 'visible' });
+    await this.page.locator('#inputUsername').fill(username);
+    await this.fillSensitive(this.page.locator('#inputPassword'), password);
+    await this.page.locator('button[type=submit]').click();
+    await this.page.getByTestId('username').waitFor({ state: 'attached' });
+  }
+
+  async logout() {
+    if (await this.isAuthDisabled()) {
+      return;
+    }
+    await this.page.getByTestId('username').click();
+    await this.page.getByTestId('log-out').waitFor({ state: 'visible' });
+    // eslint-disable-next-line playwright/no-force-option -- dropdown may be covered by overlay
+    await this.page.getByTestId('log-out').click({ force: true });
+  }
+}

+ 0 - 26
integration-tests/plugins/index.ts

@@ -1,26 +0,0 @@
-const wp = require('@cypress/webpack-preprocessor');
-
-const config: Cypress.PluginConfig = (on, config) => {
-  const options = {
-    webpackOptions: {
-      resolve: {
-        extensions: ['.ts', '.tsx', '.js'],
-      },
-      module: {
-        rules: [
-          {
-            test: /\.tsx?$/,
-            loader: 'swc-loader',
-          },
-        ],
-      },
-    },
-  };
-  on('file:preprocessor', wp(options));
-  // `config` is the resolved Cypress config
-  config.baseUrl = `${process.env.BRIDGE_BASE_ADDRESS || 'http://localhost:9000/'}`;
-  config.env.BRIDGE_KUBEADMIN_PASSWORD = process.env.BRIDGE_KUBEADMIN_PASSWORD;
-  return config;
-};
-
-module.exports = config;

+ 0 - 14
integration-tests/reporter-config.json

@@ -1,14 +0,0 @@
-{
-    "reporterEnabled": "mocha-junit-reporter, mochawesome",
-    "mochaJunitReporterReporterOptions": {
-      "mochaFile": "./screenshots/junit_cypress-[hash].xml",
-      "toConsole": false
-    },
-    "mochawesomeReporterOptions": {
-      "reportDir": "./screenshots/",
-      "reportFilename": "cypress_report",
-      "overwrite": false,
-      "html": false,
-      "json": true
-    }
-  }

+ 8 - 5
integration-tests/support/index.ts

@@ -1,6 +1,9 @@
-import './login';
+import type { Page } from '@playwright/test';
+import { expect } from '@playwright/test';
 
-export const checkErrors = () =>
-  cy.window().then((win) => {
-    assert.isTrue(!win.windowError, win.windowError);
-  });
+export async function checkErrors(page: Page) {
+  const windowError = await page.evaluate(
+    () => (window as Window & { windowError?: string }).windowError,
+  );
+  expect(windowError, 'Console JS error detected').toBeUndefined();
+}

+ 0 - 71
integration-tests/support/login.ts

@@ -1,71 +0,0 @@
-declare global {
-  namespace Cypress {
-    interface Chainable {
-      login(username?: string, password?: string): Chainable<Element>;
-      logout(): Chainable<Element>;
-    }
-  }
-  interface Window {
-    SERVER_FLAGS?: {
-      authDisabled?: boolean;
-    };
-  }
-}
-
-export const KUBEADMIN_USERNAME = 'kubeadmin';
-
-// This will add 'cy.login(...)'
-// ex: cy.login('my-user', 'my-password')
-Cypress.Commands.add(
-  'login',
-  (
-    username: string = KUBEADMIN_USERNAME,
-    password: string = Cypress.env('BRIDGE_KUBEADMIN_PASSWORD'),
-  ) => {
-    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-    const baseURL = Cypress.config('baseUrl')!;
-
-    // Make sure we clear the cookie in case a previous test failed to logout.
-    cy.clearCookie('openshift-session-token');
-
-    cy.visit(baseURL);
-
-    cy.session(
-      username,
-      () => {
-        // Check if auth is disabled (for a local development environment).
-        cy.window().then((win) => {
-          if (win.SERVER_FLAGS?.authDisabled) {
-            return;
-          }
-        });
-
-        cy.visit(baseURL);
-
-        cy.get('[data-test-id="login"]').should('be.visible');
-        cy.get('#inputUsername').type(username);
-        cy.get('#inputPassword').type(password);
-        cy.get('button[type=submit]').click();
-      },
-      {
-        cacheAcrossSpecs: true,
-        validate() {
-          cy.visit(baseURL);
-          cy.get('[data-test="username"]').should('exist');
-        },
-      },
-    );
-  },
-);
-
-Cypress.Commands.add('logout', () => {
-  // Check if auth is disabled (for a local development environment).
-  cy.window().then((win) => {
-    if (win.SERVER_FLAGS?.authDisabled) {
-      return;
-    }
-    cy.get('[data-test="username"]').click();
-    cy.get('[data-test="log-out"]').should('be.visible');
-    cy.get('[data-test="log-out"]').click({ force: true });
-  });
-});

+ 12 - 0
integration-tests/tests/auth.setup.ts

@@ -0,0 +1,12 @@
+import { test as setup } from '@playwright/test';
+import { LoginPage } from '../pages/login';
+
+// eslint-disable-next-line playwright/expect-expect -- setup test saves storageState, no assertions needed
+setup('authenticate', async ({ page }) => {
+  const loginPage = new LoginPage(page);
+  await loginPage.login();
+
+  await page.getByTestId('tour-step-footer-secondary').filter({ hasText: 'Skip tour' }).click();
+
+  await page.context().storageState({ path: 'integration-tests/.auth/user.json' });
+});

+ 0 - 89
integration-tests/tests/example-page.cy.ts

@@ -1,89 +0,0 @@
-import { checkErrors } from '../support';
-
-const PLUGIN_TEMPLATE_NAME = 'console-plugin-template';
-const PLUGIN_TEMPLATE_PULL_SPEC = Cypress.env('PLUGIN_TEMPLATE_PULL_SPEC');
-
-// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-export const isLocalDevEnvironment = Cypress.config('baseUrl')!.includes('localhost');
-
-const installHelmChart = (path: string) => {
-  // Install the plugin in a dedicated namespace using the helm chart from this repo
-  cy.exec(
-    `cd ../../console-plugin-template && ${path} upgrade -i ${PLUGIN_TEMPLATE_NAME} charts/openshift-console-plugin -n ${PLUGIN_TEMPLATE_NAME} --create-namespace --set plugin.image=${PLUGIN_TEMPLATE_PULL_SPEC}`,
-    {
-      failOnNonZeroExit: false,
-    },
-  ).then((result) => {
-    result.stderr && cy.log('Error installing helm chart: ', result.stderr);
-    result.stdout && cy.log('Successfully installed helm chart: ', result.stdout);
-  });
-
-  // Wait for the plugin deployment to be ready
-  cy.exec(
-    `oc rollout status -n ${PLUGIN_TEMPLATE_NAME} deploy/${PLUGIN_TEMPLATE_NAME} -w --timeout=300s`,
-    { timeout: 360000, failOnNonZeroExit: false },
-  );
-
-  // Wait for console pods to restart with the new plugin
-  cy.exec('oc rollout status -w deploy/console -n openshift-console --timeout=300s', {
-    timeout: 360000,
-    failOnNonZeroExit: false,
-  });
-
-  cy.visit('/k8s/cluster/operator.openshift.io~v1~Console/cluster/console-plugins');
-  cy.get(`[data-test="${PLUGIN_TEMPLATE_NAME}-status"]`).should('include.text', 'Loaded');
-};
-const deleteHelmChart = (path: string) => {
-  cy.exec(
-    `cd ../../console-plugin-template && ${path} uninstall ${PLUGIN_TEMPLATE_NAME} -n ${PLUGIN_TEMPLATE_NAME} && oc delete namespaces ${PLUGIN_TEMPLATE_NAME}`,
-    {
-      failOnNonZeroExit: false,
-    },
-  ).then((result) => {
-    cy.log('Error uninstalling helm chart: ', result.stderr);
-    cy.log('Successfully uninstalled helm chart: ', result.stdout);
-  });
-};
-
-describe('Console plugin template test', () => {
-  before(() => {
-    cy.login();
-    cy.get(`[data-test="tour-step-footer-secondary"]`).contains('Skip tour').click();
-    if (!isLocalDevEnvironment) {
-      console.log('this is not a local env, installing helm');
-
-      cy.exec('cd ../../console-plugin-template && ./install_helm.sh', {
-        failOnNonZeroExit: false,
-      }).then((result) => {
-        cy.log('Error installing helm binary: ', result.stderr);
-        cy.log('Successfully installed helm binary in "/tmp" directory: ', result.stdout);
-
-        installHelmChart('/tmp/helm');
-      });
-    } else {
-      console.log('this is a local env, not installing helm');
-
-      installHelmChart('helm');
-    }
-  });
-
-  afterEach(() => {
-    checkErrors();
-  });
-
-  after(() => {
-    if (!isLocalDevEnvironment) {
-      deleteHelmChart('/tmp/helm');
-    } else {
-      deleteHelmChart('helm');
-    }
-    cy.logout();
-  });
-
-  it('Verify the example page title', () => {
-    cy.get('[data-quickstart-id="qs-nav-home"]').click();
-    cy.get('[data-test="nav"]').contains('Plugin example').click();
-    cy.url().should('include', '/example');
-    cy.get('title').should('contain', 'Hello, plugin!');
-  });
-});

+ 73 - 0
integration-tests/tests/example-page.spec.ts

@@ -0,0 +1,73 @@
+import { execSync } from 'child_process';
+import { test, expect } from '@playwright/test';
+import { checkErrors } from '../support';
+
+const PLUGIN_TEMPLATE_NAME = 'console-plugin-template';
+// Defined in openshift/release ci-operator config as CYPRESS_PLUGIN_TEMPLATE_PULL_SPEC
+const PLUGIN_TEMPLATE_PULL_SPEC =
+  process.env.PLUGIN_TEMPLATE_PULL_SPEC ?? process.env.CYPRESS_PLUGIN_TEMPLATE_PULL_SPEC;
+
+const isLocalDevEnvironment = (process.env.BRIDGE_BASE_ADDRESS ?? 'http://localhost:9000').includes(
+  'localhost',
+);
+
+function exec(command: string, timeoutMs = 360000) {
+  try {
+    return execSync(command, { timeout: timeoutMs, encoding: 'utf-8' });
+  } catch (e) {
+    console.error('Command failed:', command, e);
+    return '';
+  }
+}
+
+function installHelmChart(helmPath: string) {
+  const result = exec(
+    `${helmPath} upgrade -i ${PLUGIN_TEMPLATE_NAME} charts/openshift-console-plugin -n ${PLUGIN_TEMPLATE_NAME} --create-namespace --set plugin.image=${PLUGIN_TEMPLATE_PULL_SPEC}`,
+  );
+  console.log('Helm install:', result);
+
+  exec(
+    `oc rollout status -n ${PLUGIN_TEMPLATE_NAME} deploy/${PLUGIN_TEMPLATE_NAME} -w --timeout=300s`,
+  );
+  exec('oc rollout status -w deploy/console -n openshift-console --timeout=300s');
+}
+
+function deleteHelmChart(helmPath: string) {
+  const result = exec(
+    `${helmPath} uninstall ${PLUGIN_TEMPLATE_NAME} -n ${PLUGIN_TEMPLATE_NAME} && oc delete namespaces ${PLUGIN_TEMPLATE_NAME}`,
+  );
+  console.log('Helm uninstall:', result);
+}
+
+test.describe('Console plugin template test', () => {
+  test.beforeAll(() => {
+    if (!isLocalDevEnvironment) {
+      console.log('this is not a local env, installing helm');
+      exec('./install_helm.sh');
+      installHelmChart('/tmp/helm');
+    } else {
+      console.log('this is a local env, not installing helm');
+      installHelmChart('helm');
+    }
+  });
+
+  test.afterEach(async ({ page }) => {
+    await checkErrors(page);
+  });
+
+  test.afterAll(() => {
+    if (!isLocalDevEnvironment) {
+      deleteHelmChart('/tmp/helm');
+    } else {
+      deleteHelmChart('helm');
+    }
+  });
+
+  test('Verify the example page title', async ({ page }) => {
+    await page.goto('/');
+    await page.locator('[data-quickstart-id="qs-nav-home"]').click();
+    await page.getByTestId('nav').getByText('Plugin example').click();
+    await expect(page).toHaveURL(/\/example/);
+    await expect(page).toHaveTitle(/Hello, plugin!/);
+  });
+});

+ 4 - 3
integration-tests/tsconfig.json

@@ -2,8 +2,9 @@
     "extends": "../tsconfig.json",
     "compilerOptions": {
         "noEmit": true,
-        "types":["cypress","node"],
+        "types": ["node"],
         "isolatedModules": false
     },
-    "include": ["../node_modules/cypress", "./**/*.ts"]
-}
+    "include": ["./**/*.ts"],
+    "exclude": ["screenshots", ".auth"]
+}

+ 6 - 14
package.json

@@ -18,22 +18,20 @@
     "i18n": "./i18n-scripts/build-i18n.sh && node ./i18n-scripts/set-english-defaults.js",
     "test": "LANG=en_US.UTF-8 jest",
     "lint": "yarn eslint src integration-tests --fix --max-warnings 0 && stylelint 'src/**/*.css' --allow-empty-input --fix",
-    "test-cypress": "cd integration-tests && cypress open",
-    "test-cypress-headless": "cd integration-tests && node --max-old-space-size=4096 ../node_modules/.bin/cypress run --browser ${BRIDGE_E2E_BROWSER_NAME:-electron}",
-    "cypress-merge": "mochawesome-merge ./integration-tests/screenshots/cypress_report*.json > ./integration-tests/screenshots/cypress.json",
-    "cypress-generate": "marge -o ./integration-tests/screenshots/ -f cypress-report -t 'OpenShift Console Plugin Template Cypress Test Results' -p 'OpenShift Cypress Plugin Template Test Results' --showPassed false --assetsDir ./integration-tests/screenshots/cypress/assets ./integration-tests/screenshots/cypress.json",
-    "cypress-postreport": "yarn cypress-merge && yarn cypress-generate",
+    "test-e2e": "playwright test --headed",
+    "test-e2e-headless": "playwright test",
     "webpack": "node -r ts-node/register ./node_modules/.bin/webpack"
   },
   "devDependencies": {
     "@babel/core": "^7.29.0",
     "@babel/preset-env": "^7.29.3",
-    "@cypress/webpack-preprocessor": "^7.1.0",
     "@openshift-console/dynamic-plugin-sdk": "4.22-latest",
     "@openshift-console/dynamic-plugin-sdk-webpack": "4.22-latest",
     "@patternfly/react-core": "^6.4.3",
     "@patternfly/react-icons": "^6.4.0",
     "@patternfly/react-table": "^6.4.3",
+    "@playwright/browser-chromium": "^1.59.1",
+    "@playwright/test": "^1.59.1",
     "@swc/core": "^1.15.32",
     "@swc/jest": "^0.2.39",
     "@testing-library/dom": "^10.4.1",
@@ -46,14 +44,12 @@
     "babel-loader": "^10.1.1",
     "copy-webpack-plugin": "^14.0.0",
     "css-loader": "^7.1.4",
-    "cypress": "^15.14.2",
-    "cypress-multi-reporters": "^2.0.5",
     "eslint": "^9.7.0",
     "eslint-config-prettier": "^10.1.8",
     "eslint-import-resolver-typescript": "^4.4.4",
-    "eslint-plugin-cypress": "^6.4.0",
     "eslint-plugin-import-x": "^4.16.2",
     "eslint-plugin-jest": "^29.15.2",
+    "eslint-plugin-playwright": "^2.10.2",
     "eslint-plugin-prettier": "^5.5.5",
     "eslint-plugin-react": "^7.37.5",
     "eslint-plugin-react-hooks": "^7.1.1",
@@ -65,10 +61,6 @@
     "jest": "^30.3.0",
     "jest-environment-jsdom": "^30.3.0",
     "jest-junit": "^17.0.0",
-    "mocha": "^11.7.5",
-    "mocha-junit-reporter": "^2.2.1",
-    "mochawesome": "^7.1.4",
-    "mochawesome-merge": "^5.1.1",
     "pluralize": "^8.0.0",
     "prettier": "^3.8.3",
     "prettier-stylelint": "^0.4.2",
@@ -88,7 +80,7 @@
     "webpack-dev-server": "^5.2.3"
   },
   "dependenciesMeta": {
-    "cypress": {
+    "@playwright/browser-chromium": {
       "built": true
     }
   },

+ 32 - 0
playwright.config.ts

@@ -0,0 +1,32 @@
+import { defineConfig } from '@playwright/test';
+
+export default defineConfig({
+  testDir: './integration-tests/tests',
+  timeout: 30000,
+  retries: 1,
+  use: {
+    baseURL: process.env.BRIDGE_BASE_ADDRESS ?? 'http://localhost:9000',
+    viewport: { width: 1920, height: 1080 },
+    screenshot: 'on',
+    ignoreHTTPSErrors: true,
+    video: 'retain-on-failure',
+    trace: 'on',
+    testIdAttribute: 'data-test',
+  },
+  projects: [
+    { name: 'setup', testMatch: /auth\.setup\.ts/ },
+    {
+      name: 'chromium',
+      use: {
+        browserName: 'chromium',
+        storageState: 'integration-tests/.auth/user.json',
+      },
+      dependencies: ['setup'],
+    },
+  ],
+  reporter: [
+    ['list'],
+    ['html', { outputFolder: 'integration-tests/results/html', open: 'never' }],
+    ['junit', { outputFile: 'integration-tests/results/junit-results.xml' }],
+  ],
+});

+ 6 - 6
test-prow-e2e.sh

@@ -3,16 +3,16 @@
 set -exuo pipefail
 
 ARTIFACT_DIR=${ARTIFACT_DIR:=/tmp/artifacts}
-SCREENSHOTS_DIR=integration-tests/screenshots
+TEST_RESULTS_DIR=integration-tests/results
 INSTALLER_DIR=${INSTALLER_DIR:=${ARTIFACT_DIR}/installer}
 
 function copyArtifacts {
-  if [ -d "$ARTIFACT_DIR" ] && [ -d "$SCREENSHOTS_DIR" ]; then
-    if [[ -z "$(ls -A -- "$SCREENSHOTS_DIR")" ]]; then
+  if [ -d "$ARTIFACT_DIR" ] && [ -d "$TEST_RESULTS_DIR" ]; then
+    if [[ -z "$(ls -A -- "$TEST_RESULTS_DIR")" ]]; then
       echo "No artifacts were copied."
     else
       echo "Copying artifacts from $(pwd)..."
-      cp -r "$SCREENSHOTS_DIR" "${ARTIFACT_DIR}/screenshots"
+      cp -r "$TEST_RESULTS_DIR" "${ARTIFACT_DIR}"
     fi
   fi
 }
@@ -33,5 +33,5 @@ if [ ! -d node_modules ]; then
   yarn install --immutable
 fi
 
-echo "Runs Cypress tests in headless mode"
-yarn test-cypress-headless
+echo "Runs Playwright tests in headless mode"
+yarn test-e2e-headless

Diferenças do arquivo suprimidas por serem muito extensas
+ 51 - 554
yarn.lock


Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff