Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
da9a8df
OO-50008 focus order for Search field fixed
ludmilaFialova Nov 5, 2025
fac3ecd
OO-52367 Spacebar opens Search popup
ludmilaFialova Nov 11, 2025
384ab71
OO-52367 Esc and Space works
ludmilaFialova Nov 13, 2025
929951e
OO-52365 labels and controls
ludmilaFialova Nov 17, 2025
20ab2ce
NUI-6263 hidden icon
ludmilaFialova Nov 17, 2025
e8b290c
NUI-6263 Recent searches accessible by Tab key
ludmilaFialova Nov 17, 2025
2431d79
OO-55517 icon component role
ludmilaFialova Nov 27, 2025
3b42875
OO-55517 image component role
ludmilaFialova Nov 27, 2025
46423db
OO-55517 computeA11yForGraphic
ludmilaFialova Nov 27, 2025
4e3d011
NUI-6263 compute-version-local script
ludmilaFialova Jan 14, 2026
995b307
NUI-6263 yarn run --cwd packages/bits lint:fix
ludmilaFialova Jan 14, 2026
42ed6da
NUI-6263 ng v17 upgrade of the Image component
ludmilaFialova Jan 15, 2026
278a39c
NUI-6263 ng v17 upgrade of the Search component
ludmilaFialova Jan 15, 2026
8b1f4fd
NUI-6263 ng v17 upgrade of the icon component
ludmilaFialova Jan 15, 2026
f0982d6
NUI-6263 step back because of failed Application bundle generation in…
ludmilaFialova Jan 15, 2026
f043ff5
NUI-6263 bits-unit-tests fixed
ludmilaFialova Jan 16, 2026
a6e5ff4
NUI-6263 fix legend E2E test timing issue
ludmilaFialova Jan 16, 2026
361194b
NUI-6263 different color for hover and focus
ludmilaFialova Jan 20, 2026
02e3e7d
NUI-6263 muted tests
ludmilaFialova Feb 2, 2026
71c95e8
known_hosts for CircleCI
ludmilaFialova Feb 5, 2026
e04a651
e2e tests fixed
ludmilaFialova Feb 4, 2026
32c9378
playwright e2e tests fixed
ludmilaFialova Feb 5, 2026
12d0861
CircleCI tests 2nd try
ludmilaFialova Feb 5, 2026
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
7 changes: 5 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,17 @@ aliases:
then
echo "skipping npm install as it was restored from cache. Running only postinstall"
else
yarn install --frozen-lockfile
yarn install --frozen-lockfile --ignore-scripts
fi

commands:
install-deps:
description: "Install deps"
steps:
- *cache_restore
- run:
name: Add GitHub to known hosts
command: mkdir -p ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts
- *install_dependencies
- *cache_save

Expand All @@ -51,7 +54,7 @@ executors:

playwright:
docker:
- image: mcr.microsoft.com/playwright:v1.52.0-noble
- image: mcr.microsoft.com/playwright:v1.58.1-noble
working_directory: ~/nova
environment:
NODE_ENV: development
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ node_modules
response.txt
.yarn
.yarnrc.yml
test-results/.last-run.json
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@
"zone.js": "0.15.0"
},
"resolutions": {
"d3-color": "3.1.0"
"d3-color": "3.1.0",
"tablesort": "5.3.0"
},
"engines": {
"node": ">=20"
Expand Down Expand Up @@ -127,7 +128,7 @@
"trigger-pipeline-build-ci": "bash scripts/trigger-pipeline-build",
"verify-ci": "bash scripts/verify-published"
},
"version": "19.0.0",
"version": "19.0.2-0",
"workspaces": [
"packages/*"
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import { Component } from "@angular/core";
import { Component, OnInit } from "@angular/core";
import {
FormBuilder,
FormControl,
Expand All @@ -45,7 +45,7 @@ const CHART_PALETTE_CS1: string[] = [
styles: [],
standalone: false,
})
export class ColorPickerBasicExampleComponent {
export class ColorPickerBasicExampleComponent implements OnInit {
public myForm: FormGroup<{ backgroundColor: FormControl<string | null> }>;
public colors: string[] = CHART_PALETTE_CS1;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import { Component } from "@angular/core";
import { Component, OnInit } from "@angular/core";
import {
FormBuilder,
FormControl,
FormGroup,
} from "@angular/forms";

import { HTML_COLORS, IPaletteColor } from "../../../../../../src/constants/color-picker.constants";


Expand All @@ -33,7 +34,7 @@ import { HTML_COLORS, IPaletteColor } from "../../../../../../src/constants/colo
styles: [],
standalone: false,
})
export class ColorPickerPaletteExampleComponent {
export class ColorPickerPaletteExampleComponent implements OnInit {
public myForm: FormGroup<{ backgroundColor: FormControl<string | null> }>;
public colorPalette: IPaletteColor[] = Array.from(HTML_COLORS.entries())
.map(([label, color]) => ({label,color}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import { Component } from "@angular/core";
import { Component, OnInit } from "@angular/core";
import {
FormBuilder,
FormControl,
FormGroup,
} from "@angular/forms";

import { HTML_COLORS, IPaletteColor } from "../../../../../../src/constants/color-picker.constants";


Expand All @@ -33,7 +34,7 @@ import { HTML_COLORS, IPaletteColor } from "../../../../../../src/constants/colo
styles: [],
standalone: false,
})
export class ColorPickerSelectExampleComponent {
export class ColorPickerSelectExampleComponent implements OnInit {
public myForm: FormGroup<{ backgroundColor: FormControl<string | null> }>;
public colorPalette: IPaletteColor[] = Array.from(HTML_COLORS.entries())
.map(([label, color]) => ({label,color}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
// THE SOFTWARE.

import { NgModule } from "@angular/core";
import { RouterModule } from "@angular/router";
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
import { RouterModule } from "@angular/router";

import {
DEMO_PATH_TOKEN,
Expand All @@ -30,11 +30,12 @@ import {
NuiPopoverModule,
SrlcStage,
} from "@nova-ui/bits";
import { getDemoFiles } from "../../../static/demo-files-factory";

import { ColorPickerBasicExampleComponent } from "./color-picker-basic/color-picker-basic.example.component";
import { ColorPickerExampleComponent } from "./color-picker-docs/color-picker-docs.example.component";
import { ColorPickerPaletteExampleComponent } from "./color-picker-palette/color-picker-palette.example.component";
import { ColorPickerSelectExampleComponent } from "./color-picker-select/color-picker-select.example.component";
import { ColorPickerExampleComponent } from "./color-picker-docs/color-picker-docs.example.component";
import { getDemoFiles } from "../../../static/demo-files-factory";

const routes = [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { test, Helpers } from "../../setup";
const rulesToDisable: string[] = ["aria-allowed-role", "nested-interactive"];

test.describe("a11y: checkbox", () => {
test.test.beforeEach(async ({ page }) => {
test.beforeEach(async ({ page }) => {
await Helpers.prepareBrowser("checkbox/checkbox-visual-test", page);
});

Expand Down
22 changes: 10 additions & 12 deletions packages/bits/e2e/components/datepicker/datepicker.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,22 +410,20 @@ test.describe("USERCONTROL datepicker", () => {
test("should save hour correctly when triggered at 23:00 - 0:00", async () => {
await datepickerWithInitAndPreserve.clickInput();
await datepickerWithInitAndPreserve.selectDate(5);
const oldValue = await Atom.find<Atom>(
Atom,
initDateValueIdPreserved
)
.getLocator()
.textContent();
const oldValue = (
await Atom.find<Atom>(Atom, initDateValueIdPreserved)
.getLocator()
.textContent()
)?.trim();
await datepickerWithInitAndPreserve.clickInput();
await datepickerWithInitAndPreserve.selectDate(
moment().date() > 15 ? 10 : 20
);
const newValue = await Atom.find<Atom>(
Atom,
initDateValueIdPreserved
)
.getLocator()
.textContent();
const newValue = (
await Atom.find<Atom>(Atom, initDateValueIdPreserved)
.getLocator()
.textContent()
)?.trim();

expect(newValue).not.toBe(oldValue);
expect(moment(newValue).hour()).toBe(moment(oldValue).hour());
Expand Down
2 changes: 1 addition & 1 deletion packages/bits/e2e/components/dialog/dialog.a11y.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import { DialogAtom } from "./dialog.atom";
import { test, Helpers } from "../../setup";

describe("a11y: dialog", () => {
test.describe("a11y: dialog", () => {
// disabling the rule until NUI-6014 is addressed
const rulesToDisable: string[] = [
"color-contrast",
Expand Down
2 changes: 1 addition & 1 deletion packages/bits/e2e/components/icon/icon.a11y.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IconAtom } from "./icon.atom";
import { test, Helpers } from "../../setup";

describe("a11y: icon", () => {
test.describe("a11y: icon", () => {
const rulesToDisable: string[] = [
"duplicate-id", // has nothing to do with the icons
];
Expand Down
2 changes: 1 addition & 1 deletion packages/bits/e2e/components/menu/menu.a11y.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import { MenuAtom } from "./menu.atom";
import { test, Helpers } from "../../setup";

describe("a11y: menu", () => {
test.describe("a11y: menu", () => {
const rulesToDisable: string[] = [
"color-contrast", // NUI-6014
"scrollable-region-focusable", // NUI-5935, NUI-6007
Expand Down
18 changes: 3 additions & 15 deletions packages/bits/e2e/components/menu/menu.atom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,29 +150,17 @@ export class MenuAtom extends Atom {
}

public getSelectedSwitchElements(): Locator {
return this.getLocator().locator(".nui-switched");
return this.getLocator().locator("nui-switch .nui-switched");
}

public async getSelectedMenuSwitches(): Promise<MenuItemAtom[]> {
const items = this.getSelectedSwitchElements();
const count = await items.count();
const selected: MenuItemAtom[] = [];
for (let i = 0; i < count; i++) {
selected.push(
Atom.findIn<MenuItemAtom>(MenuItemAtom, items.nth(i))
);
}
return selected;
public async getSelectedSwitchesCount(): Promise<number> {
return this.getSelectedSwitchElements().count();
}

public async getSelectedCheckboxesCount(): Promise<number> {
return (await this.getSelectedMenuCheckboxes()).length;
}

public async getSelectedSwitchesCount(): Promise<number> {
return (await this.getSelectedMenuSwitches()).length;
}

public getAppendToBodyMenu(): Locator {
if (!this.menuContentId) {
throw new Error("menuContentId is not set");
Expand Down
19 changes: 10 additions & 9 deletions packages/bits/e2e/components/menu/menu.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,11 @@ test.describe("USERCONTROL Menu", () => {
expect(await menu.getSelectedSwitchesCount()).toEqual(1);

await Helpers.pressKey("Enter");
await menu.isMenuOpened();
expect(await menu.getSelectedSwitchesCount()).toEqual(0);

await Helpers.pressKey("Enter");
await menu.isMenuOpened();
await Helpers.pressKey("ArrowDown");
await Helpers.pressKey("Enter");
expect(await menu.getSelectedSwitchesCount()).toEqual(2);
Expand Down Expand Up @@ -186,22 +188,21 @@ test.describe("USERCONTROL Menu", () => {
test.describe("> append-to-body", () => {
test("should check and uncheck checkbox in menu item", async () => {
await appendToBody.toggleMenu();
await Helpers.pressKey("ArrowDown");
// Find the first checkbox in the appendToBody menu
// Find all checkboxes in the appendToBody menu
const menuLocator = appendToBody.getAppendToBodyMenu();
const checkboxes = menuLocator.locator("nui-checkbox");
const firstCheckbox = checkboxes.first();

// Check class for checked state
const isChecked = async () =>
(await firstCheckbox.getAttribute("class")).includes(
"nui-checkbox--checked"
);
expect(await isChecked()).toBe(false);
await expect(firstCheckbox).not.toHaveClass(/nui-checkbox--checked/);

await Helpers.pressKey("ArrowDown");
await Helpers.pressKey("Enter");
expect(await isChecked()).toBe(true);
await expect(firstCheckbox).toHaveClass(/nui-checkbox--checked/);

// Return to initial state
await Helpers.pressKey("Enter");
expect(await isChecked()).toBe(false);
await expect(firstCheckbox).not.toHaveClass(/nui-checkbox--checked/);
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import { PaginatorAtom } from "./paginator.atom";
import { test, Helpers } from "../../setup";

describe("a11y: paginator", () => {
test.describe("a11y: paginator", () => {
const rulesToDisable: string[] = ["nested-interactive"];

test.beforeEach(async ({ page }) => {
Expand Down
13 changes: 9 additions & 4 deletions packages/bits/e2e/components/paginator/paginator.atom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,15 @@ export class PaginatorAtom extends Atom {
}

public async pageLinkVisible(pageNumber: number): Promise<boolean> {
const li = this.getLocator().locator(
`.nui-paginator__list li[value='${pageNumber}']`
);
return await li.isVisible();
return this.getPageLinkLocator(pageNumber).isVisible();
}

public getPageLinkLocator(pageNumber: number): Locator {
return this.getLocator()
.locator(
`.nui-paginator__list li[value='${pageNumber}']:not([title*='Previous']):not([title*='Next']):not([title*='Pages'])`
)
.first();
}

public async ellipsedPageLinkClick(pageNumber: number): Promise<void> {
Expand Down
6 changes: 3 additions & 3 deletions packages/bits/e2e/components/paginator/paginator.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,9 @@ test.describe("USERCONTROL paginator", () => {
expect(
await adjacentPaginator.pageLinkVisible(pageTwenty + adjacent)
).toBe(true);
expect(
await adjacentPaginator.pageLinkVisible(pageCountAdjacent)
).toBe(true);
await expect(
adjacentPaginator.getPageLinkLocator(pageCountAdjacent)
).toBeVisible();
for (
let i = pageTwenty + adjacent + 1;
i < pageCountAdjacent;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { ProgressAtom } from "./progress.atom";
import { test, Helpers } from "../../setup";
import { ButtonAtom } from "../button/button.atom";

describe("a11y: progress", () => {
test.describe("a11y: progress", () => {
const rulesToDisable: string[] = ["nested-interactive"];
let startProgressBasic: ButtonAtom;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import { SelectV2Atom } from "./select-v2.atom";
import { test, Helpers, Animations } from "../../setup";

describe("a11y: select-v2", () => {
test.describe("a11y: select-v2", () => {
const rulesToDisable: string[] = [
"color-contrast", // NUI-6014
"nested-interactive",
Expand Down
2 changes: 1 addition & 1 deletion packages/bits/e2e/components/spinner/spinner.a11y.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import { SpinnerAtom } from "./spinner.atom";
import { test, Helpers, Animations } from "../../setup";

describe("a11y: spinner", () => {
test.describe("a11y: spinner", () => {
const rulesToDisable: string[] = [];

test.beforeEach(async ({ page }) => {
Expand Down
4 changes: 2 additions & 2 deletions packages/bits/e2e/components/spinner/spinner.atom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ export class SpinnerAtom extends Atom {
}

public async waitForDisplayed(
timeout: number = SpinnerAtom.defaultDelay * 1.5
timeout: number = SpinnerAtom.defaultDelay * 5
): Promise<void> {
await expect(this.root).toBeVisible({ timeout });
}

public async waitForHidden(
timeout: number = SpinnerAtom.defaultDelay * 1.5
timeout: number = SpinnerAtom.defaultDelay * 5
): Promise<void> {
await expect(this.root).toBeHidden({ timeout });
}
Expand Down
6 changes: 3 additions & 3 deletions packages/bits/e2e/components/spinner/spinner.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,23 @@ test.describe("USERCONTROL Spinner", () => {
test("with delayed set", async () => {
await delayedSpinner.toBeHidden();
await delayedButton.click();
await delayedSpinner.waitForDisplayed(spinnerDelay * 2);
await delayedSpinner.waitForDisplayed(spinnerDelay * 5);
await delayedButton.click();
await delayedSpinner.toBeHidden();
});

test("without delay", async () => {
await spinner2.toBeHidden();
await button2.click();
await spinner2.waitForDisplayed(SpinnerAtom.defaultDelay * 2);
await spinner2.waitForDisplayed(SpinnerAtom.defaultDelay * 5);
await button2.click();
await spinner2.toBeHidden();
});
});

test("should have 'small' default size if no 'size' input provided", async () => {
await button2.click();
await spinner2.waitForDisplayed(SpinnerAtom.defaultDelay * 2);
await spinner2.waitForDisplayed(SpinnerAtom.defaultDelay * 5);
await expect(spinner2.getLocator()).toHaveClass(
/nui-spinner__container--small/
);
Expand Down
Loading