Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
f33948d
playwright e2e for nova bits
PavloPoimanov May 20, 2025
6245f12
go
PavloPoimanov May 26, 2025
1455edc
revert npmx
PavloPoimanov May 26, 2025
f4af405
not in
PavloPoimanov May 26, 2025
110a613
optimize
PavloPoimanov May 26, 2025
b16c722
optimize not work
PavloPoimanov May 26, 2025
4dda0d6
stupid bash
PavloPoimanov May 26, 2025
085fe76
stupid bash
PavloPoimanov May 26, 2025
6f18ee5
evalues
PavloPoimanov May 26, 2025
eb242a6
wiutos
PavloPoimanov May 26, 2025
fae7db9
wiutos
PavloPoimanov May 26, 2025
1e41573
clean up
PavloPoimanov May 26, 2025
d8a936a
only this way
PavloPoimanov May 26, 2025
ef66199
only this way
PavloPoimanov May 27, 2025
062ae78
try this
PavloPoimanov May 27, 2025
c5d19d9
now optimized?
PavloPoimanov May 27, 2025
2c699c3
now optimized?
PavloPoimanov May 27, 2025
1fee7e2
correct
PavloPoimanov May 27, 2025
10794e7
clean
PavloPoimanov May 27, 2025
7bb337d
clean
PavloPoimanov May 27, 2025
43b5c1a
clean
PavloPoimanov May 27, 2025
e143d17
rename
PavloPoimanov May 27, 2025
626a2a6
start spotting weak places of protractor
PavloPoimanov May 27, 2025
dc429da
chips tests
PavloPoimanov May 27, 2025
cea1acd
datapicker,track
PavloPoimanov May 27, 2025
5577480
lets check chips test
PavloPoimanov May 28, 2025
6c49298
lets check chips test
PavloPoimanov May 28, 2025
7de3f29
no fail locally
PavloPoimanov May 28, 2025
cbd338e
datapicker tests
PavloPoimanov May 28, 2025
13d6796
button test fixes
PavloPoimanov May 28, 2025
c5712e0
progress
PavloPoimanov May 28, 2025
c280bba
local work with tests
PavloPoimanov Sep 1, 2025
212d776
feat(ci/playwright): update TypeScript Angular component instructions…
PavloPoimanov Oct 10, 2025
8c6a89f
wip
pavlo-poimanov Sep 8, 2025
640243b
(feat) dialog tests
PavloPoimanov Oct 10, 2025
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
115 changes: 70 additions & 45 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,41 @@ version: 2.1
orbs:
browser-tools: circleci/browser-tools@1.4.0

aliases:
- &cache_restore
restore_cache:
keys:
- dependencies-{{ checksum "yarn.lock" }}
- &cache_save
save_cache:
paths:
- ./node_modules
key: dependencies-{{ checksum "yarn.lock" }}

- &install_dependencies
run:
working_directory: ~/nova
name: Installing node dependencies (if necessary)
command: |
if [ -d "node_modules" ];
then
echo "skipping npm install as it was restored from cache. Running only postinstall"
else
yarn install --frozen-lockfile
fi

commands:
install-deps:
description: "Install deps"
steps:
- *cache_restore
- *install_dependencies
- *cache_save

reuse-cache:
description: "Reuse cache among the builds"
steps:
- restore_cache:
key: deps-{{ checksum "yarn.lock" }}
- *cache_restore

executors:
node:
Expand All @@ -19,12 +48,19 @@ executors:
docker:
- image: cimg/node:20.18.1
working_directory: ~/nova

playwright:
docker:
- image: mcr.microsoft.com/playwright:v1.52.0-noble
working_directory: ~/nova
environment:
NODE_ENV: development
ubuntu:
machine:
image: ubuntu-2204:2022.10.2
working_directory: ~/nova
environment:
USE_CACHE: "true"
USE_CACHE: "true"

jobs:
prepare:
Expand All @@ -34,42 +70,14 @@ jobs:
BUILD_COUNTER: << pipeline.number >>
steps:
- checkout
- restore_cache:
key: deps-{{ checksum "yarn.lock" }}
- run:
working_directory: ~/nova
name: Installing node dependencies (if necessary)
command: |
if [ -d "node_modules" ];
then
echo "skipping npm install as it was restored from cache. Running only postinstall"
else
yarn install --frozen-lockfile
fi
- save_cache:
key: deps-{{ checksum "yarn.lock" }}
paths:
- ./node_modules
- run:
working_directory: ~/nova
name: Check styling
command: |
yarn prettier-check || true
EXIT_CODE=$?
echo "Exit Code: $EXIT_CODE"
if [ $EXIT_CODE -ne 0 ]; then
echo "Has styling issues but continuing..."
fi
# Exit with 0 to indicate success to CircleCI (override the failure)
exit 0
when: always

- install-deps
- persist_to_workspace:
root: ~/nova
paths:
- .git
- packages
- scripts
- test
- .editorconfig
- .eslintignore
- .eslintrc.js
Expand Down Expand Up @@ -148,17 +156,8 @@ jobs:
- browser-tools/install-chrome
- attach_workspace:
at: ~/nova
- run:
name: Check git diff to see if builds should skip e2e
command: |
circleci-agent step halt
if [ -f packages/bits/package-cached ] && [ "$USE_CACHE" == "true" ]; then
echo "This package was restored from cache so we're skipping e2e tests"
circleci-agent step halt
fi
echo "not skiped"
- restore_cache:
key: bits-dist-{{ checksum "packages/bits/git-commit" }}
key: bits-dist-{{ checksum "packages/bits/git-commit" }}
- reuse-cache
- run:
name: Start Selenium docker image
Expand Down Expand Up @@ -189,7 +188,7 @@ jobs:
circleci step halt
fi
- restore_cache:
key: bits-dist-{{ checksum "packages/bits/git-commit" }}
key: bits-dist-{{ checksum "packages/bits/git-commit" }}
- reuse-cache
- run:
name: Start Selenium docker image
Expand Down Expand Up @@ -220,7 +219,7 @@ jobs:
circleci step halt
fi
- restore_cache:
key: bits-dist-{{ checksum "packages/bits/git-commit" }}
key: bits-dist-{{ checksum "packages/bits/git-commit" }}
- reuse-cache
- run:
name: Start Selenium docker image
Expand All @@ -233,6 +232,29 @@ jobs:
- run:
name: Cleanup
command: docker-compose down -v --rmi=local
bits-e2e-test-playwright:
executor: playwright
parallelism: 4
steps:
- attach_workspace:
at: ~/nova
- install-deps
- restore_cache:
key: bits-dist-{{ checksum "packages/bits/git-commit" }}
- run:
working_directory: ~/nova/packages/bits
name: Run tests
command: |
NODE_INDEX="$((${CIRCLE_NODE_INDEX}+1))";
SHARD="${NODE_INDEX}/${CIRCLE_NODE_TOTAL}";
yarn run e2e:playwright:ci --shard=${SHARD}
- store_artifacts:
path: ./packages/bits/playwright-report
destination: playwright-report-first
- store_artifacts:
path: /tmp/artifacts
- store_artifacts:
path: ./packages/bits/test-results
bits-pack:
executor: node
steps:
Expand Down Expand Up @@ -670,6 +692,9 @@ workflows:
- bits-e2e-test:
requires:
- bits-build
- bits-e2e-test-playwright:
requires:
- bits-build
- bits-visual-test:
requires:
- bits-build
Expand Down
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
max-old-space-size=16384
registry="https://registry.npmjs.org/"
9 changes: 7 additions & 2 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## [19.0.1] 📅 2025-05-26
### Initial playwrite e2e tests migration


## [19.0.0] 📅 2025-05-26
### Angular upgrade 19

## [17.0.0] 📅 2025-04-20
### Angular upgrade 17

Expand Down Expand Up @@ -121,8 +128,6 @@

- `@nova-ui/bits` | _NUI-6163_ | Added _preventRowClick_ flag on **nui-repeater** (to be used when items contain clickable content)

</details>

## [12.0.3] 📅 2022-04-14

### Bugfix
Expand Down
63 changes: 63 additions & 0 deletions docs/E2E-MIGRATION-PLAYWRITE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Protractor to Playwright Migration Strategy

## Overview

This document outlines the strategy to migrate UI tests from **Protractor** to **Playwright** for the [SolarWinds NOVA](https://github.com/solarwinds/nova) Angular UI component library.

The main goals of the migration are:
- Minimize the time and effort involved.
- Preserve existing test coverage and reliability.
- Enable modern E2E testing capabilities.
- Integrate seamlessly with **CircleCI** for CI/CD workflows.

---
## Why Playwright?

Below is a comparison of the leading modern E2E frameworks, evaluated against the criteria most relevant to migrating from Protractor in an Angular-based, component-driven library like NOVA.

| Feature / Tool | **Playwright** | **Cypress** | **WebdriverIO (WDIO)** | **Nightwatch** |
| ------------------------------------- | --------------------------------------------- | ---------------------------------------------- | --------------------------------------------- | ------------------------------------------- |
| **Angular Compatibility** | ✅ Excellent (async-friendly, stable selectors)| ⚠️ Good, but manual waits needed for stability | ⚠️ Needs plugins or manual waits | ⚠️ Angular support improving, not native |
| **Cross-Browser Support** | ✅ Chromium, Firefox, WebKit | ⚠️ Chrome + limited Firefox, no WebKit | ✅ Chromium, Firefox, Safari, IE via Selenium | ✅ Similar to WDIO (uses Selenium or DevTools)|
| **Parallel Test Execution** | ✅ Native via workers | ✅ Built-in with Dashboard/paid CI | ✅ Native support via CLI | ✅ Via Test Runner |
| **Test Stability & Auto-waiting** | ✅ Excellent built-in waiting | ⚠️ Good, but flakiness with dynamic content | ⚠️ Manual waits often required | ⚠️ Basic auto-wait; prone to flakiness |
| **Headless Mode & CI Readiness** | ✅ First-class support | ✅ Well supported | ✅ Strong via Selenium or native | ✅ Basic CI support |
| **API Design & Developer Experience** | ✅ Modern, async/await, fast | ✅ Very developer-friendly | ⚠️ Verbose, but flexible | ⚠️ Older syntax, improving slowly |
| **Migration Effort from Protractor** | ✅ Easier (modern syntax, async, no Selenium) | ⚠️ Medium (some Protractor patterns break) | ❌ Harder (Selenium-based, different mindset) | ❌ Legacy-like; high boilerplate |
| **Test Debugging Tools** | ✅ Codegen, Trace Viewer, Inspector | ✅ Excellent UI with time-travel debugging | ⚠️ Limited tooling | ⚠️ Basic CLI logs |
| **Community & Maintenance** | ✅ Backed by Microsoft, fast-growing | ✅ Strong community, open-source | ✅ Active, mature, slower-moving | ⚠️ Smaller, older community |


---

## Migration Plan

### Phase 1: Preparation

- ✅ Audit existing Protractor test cases and group by priority.
- ✅ Set up Playwright in the monorepo.
- ✅ Configure initial Playwright test suite for a single package (e.g. `common`).
- ✅ Add Playwright to **CircleCI** configuration for basic E2E validation.

### Phase 2: Pilot

- 🔄 Rewrite a small set of core Protractor tests using Playwright:
- Buttons
- Links
- Modals/Wizards
- Table (Angular CDK integration)
- ✅ Validate that feature parity exists.
- ✅ Use Playwright Codegen (`npx playwright codegen`) to speed up test creation.
- ✅ Confirm test behavior across Chromium, Firefox, WebKit.

### Phase 3: Dual Operation

- ⚙️ Continue running Protractor alongside Playwright.
- 🔁 Gradually migrate all Protractor suites by priority.
- ✅ Ensure test stability before deprecating corresponding Protractor tests.
- 🔐 Migrate test utilities/helpers to Playwright-friendly utilities.

### Phase 5: Cleanup
- 🚫 Remove Protractor dependencies from package.json.
- 🧹 Clean up tsconfig and helper utilities no longer needed.
- 📘 Update documentation and developer onboarding guides.
73 changes: 73 additions & 0 deletions docs/E2E/A11Y.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# ♿ Accessibility (a11y) Testing in Playwright

Playwright provides built-in support for accessibility (a11y) testing through its integration with the [Accessibility Tree](https://developer.mozilla.org/en-US/docs/Web/Accessibility/Accessibility_tree). This document covers how to set up, run, and write accessibility tests using Playwright.

---

## 📦 1. Setup

If you're using `@playwright/test`, no additional packages are needed.

### ✅ Install Playwright (if not already)

```bash
npm install --save-dev @playwright/test
npx playwright install
```

## 🚀 2. How to Run Accessibility Tests
You can run accessibility checks as part of your test suite using the accessibility.snapshot() API, which returns the accessibility tree of the current page or element.

### 🧪 Run all Playwright tests:
```bash
yarn run a11y:playwright
```

## ✍️ 3-a. How to Write a11y Tests
Playwright allows you to programmatically inspect the accessibility tree.

✅ Example: Basic a11y Snapshot Test
```ts
import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';

test.describe('Accessibility Tests', () => {
test('should have no detectable accessibility violations on load', async ({ page }) => {
await page.goto('https://your-website.com');
const accessibilityScanResults = await new AxeBuilder({ page }).analyze();
expect(accessibilityScanResults.violations).toEqual([]);
});
});

```
## 🧪 3-b. Writing Tests with the Shared Fixture
Use the shared `runA11yScan` helper in your tests.

```ts
// tests/accessibility.spec.ts
import { test, expect } from '../fixtures/a11y-fixture';

test.describe('Accessibility checks', () => {
test('Page should have no a11y violations', async ({ page, runA11yScan }) => {
await page.goto('https://your-website.com');
await runA11yScan();
});

test('Only header section should pass a11y rules', async ({ page, runA11yScan }) => {
await page.goto('https://your-website.com');
await runA11yScan('#main-header');
});
});

```
✅ Benefits of Using Fixtures

```text
Centralized axe-core config (e.g., tags, rules, includes).
Less repetitive setup code.
Scalable for large test suites.
```

### 🧩 Optional: HTML Report with axe-html-reporter
You can extend the fixture to generate HTML reports by integrating the axe-html-reporter.

Loading