Skip to content
Draft

Demo #810

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
121 changes: 73 additions & 48 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,65 @@ 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 --ignore-scripts
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:
docker:
- image: cimg/node:20.18.1
- image: cimg/node:20.19.0
working_directory: ~/nova

node-browsers:
docker:
- image: cimg/node:20.18.1
- image: cimg/node:20.19.0
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 @@ -639,7 +661,7 @@ jobs:
environment:
SOURCE_BRANCH: main
CREATE_RELEASE_BRANCH: "true"
RELEASE_BRANCH: release/v19.0.x
RELEASE_BRANCH: release/v20.0.x
INCREMENT_TYPE: major
steps:
- add_ssh_keys
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
7 changes: 5 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,12 @@ module.exports = {
"@angular-eslint/no-empty-lifecycle-method": "off",
"@angular-eslint/no-host-metadata-property": "off",
// todo migrate all components to standalone
"@angular-eslint/prefer-standalone": "off",
"@angular-eslint/prefer-standalone": "warn",
// todo breaking change to clients output native
"@angular-eslint/no-output-native": "off",
"@angular-eslint/no-output-native": "warn",
// todo migrate all components to use inject instead of constructor
// migrating script is not working - https://github.com/angular/angular/issues/66074
"@angular-eslint/prefer-inject": "warn",
/******************************
* Typescript-specific rules
*******************************/
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/
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,15 @@ Please let us know! But...before submitting a feature request or issue report, p
## Troubleshooting

Find tips for solving some common development environment problems [here](./docs/TROUBLESHOOTING.md#troubleshooting).

## End-to-End (E2E) Testing with Playwright

Nova supports modern E2E testing using [Playwright](https://playwright.dev/). Playwright is recommended for new E2E tests, while Protractor is retained for legacy support.

### 📖 Playwright E2E Documentation
- **Accessibility (a11y) Testing:** See [`docs/E2E/A11Y.md`](./docs/E2E/A11Y.md) for setup, running, and writing accessibility tests with Playwright and axe-core.
- **Project Structure:** See [`docs/E2E/STRUCTURE.md`](./docs/E2E/STRUCTURE.md) for E2E folder and config organization, including Playwright config location.

#### More E2E Docs
- Additional E2E topics: [docs/E2E/](./docs/E2E/)
- Legacy Protractor info: see below and in [HOW_TO.md](./docs/HOW_TO.md#e2e-testing)
19 changes: 15 additions & 4 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
# Changelog
## [20.0.0] 📅 2025-10-01
### Angular upgrade 20

## [17.0.1] 📅 2025-07-31

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

## [19.0.2] 📅 2025-09-30
### Added
- `@nova-ui/bits` | Added colorpicker
- `@nova-ui/bits` | Added nui-tab heading is accessible with keyboard

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

## [17.0.3] 📅 2025-08-06
### Fixes
- `@nova-ui/dashboards` | Fix kpi scale brokers duplication on config change

- `@nova-ui/dashboards` | Added ability to globaly disable refreshers

## [17.0.0] 📅 2025-04-20
### Angular upgrade 17
Expand Down Expand Up @@ -125,8 +138,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
81 changes: 81 additions & 0 deletions docs/E2E-MIGRATION-PLAYWRITE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# 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.

---

## 💡 Tip: use Copilot prompts to speed up migration

Copilot can help you convert repetitive Protractor patterns to Playwright and keep the team consistent.

A couple prompt ideas that work well:

- “Migrate this Protractor spec to Playwright. Keep the same assertions, but replace selectors with Nova **Atoms** where possible. Prefer `Atom.find` / `Atom.findIn` and Atom assertion helpers (e.g., `toBeVisible`, `toContainClass`). Don’t use fixed timeouts.”
- “Refactor this Playwright test to avoid raw `page.locator(...)` usage. Create or reuse an Atom so the test is framework-agnostic.”

If you’re migrating a file, it also helps to ask Copilot to do it in small steps:

1) rewrite navigation + setup
2) replace selectors
3) replace assertions
4) remove manual waits

---
## 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 (DONE)

- ✅ 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 (DOING)

- 🔄 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.
Loading