From 38880e50c4abacfe24a299d8ad2efc5a46ff13a3 Mon Sep 17 00:00:00 2001 From: Robb Hamilton Date: Mon, 10 Aug 2026 15:47:09 -0400 Subject: [PATCH 1/3] OCPBUGS-105519: Fix flaky web-terminal-config.spec.ts e2e tests The tests navigate directly to a deep URL without first warming up the SPA. The first navigation can land on the OAuth login page if the session has not been fully established in the browser context. Add a beforeEach hook calling warmupSPA to match the pattern used by all other test suites. Co-Authored-By: Claude Opus 4.6 --- frontend/e2e/tests/webterminal/web-terminal-config.spec.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frontend/e2e/tests/webterminal/web-terminal-config.spec.ts b/frontend/e2e/tests/webterminal/web-terminal-config.spec.ts index eab20a26918..86b051e88d4 100644 --- a/frontend/e2e/tests/webterminal/web-terminal-config.spec.ts +++ b/frontend/e2e/tests/webterminal/web-terminal-config.spec.ts @@ -1,4 +1,5 @@ import { test, expect } from '../../fixtures'; +import { warmupSPA } from '../../pages/base-page'; import { WebTerminalConfigPage } from '../../pages/web-terminal-config-page'; import { ensureWebTerminalOperatorInstalled, @@ -19,6 +20,10 @@ test.describe('Customization of web terminal options', () => { await uninstallWebTerminalOperator(k8sClient); }); + test.beforeEach(async ({ page }) => { + await warmupSPA(page); + }); + test( 'navigate to Web Terminal Configuration page', async ({ page }) => { From c68a53c55eeb4bbd0aa1ab71073f715db99451c7 Mon Sep 17 00:00:00 2001 From: Robb Hamilton Date: Mon, 10 Aug 2026 15:58:14 -0400 Subject: [PATCH 2/3] OCPBUGS-105519: Add warmupSPA to knative-ci.spec.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same missing warmupSPA issue as web-terminal-config.spec.ts — tests navigate to deep URLs without first establishing the SPA session, causing intermittent failures stuck on the login page. Co-Authored-By: Claude Opus 4.6 --- frontend/e2e/tests/knative/serverless/knative-ci.spec.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frontend/e2e/tests/knative/serverless/knative-ci.spec.ts b/frontend/e2e/tests/knative/serverless/knative-ci.spec.ts index 4596cd9d006..567e1909dc5 100644 --- a/frontend/e2e/tests/knative/serverless/knative-ci.spec.ts +++ b/frontend/e2e/tests/knative/serverless/knative-ci.spec.ts @@ -1,6 +1,7 @@ import { execFileSync } from 'child_process'; import { test, expect } from '../../../fixtures'; +import { warmupSPA } from '../../../pages/base-page'; import { AddFlowPage } from '../../../pages/knative/add-flow-page'; import { AdminEventingPage } from '../../../pages/knative/admin-eventing-page'; import { TopologyKnativePage } from '../../../pages/knative/topology-knative-page'; @@ -39,6 +40,10 @@ test.describe( await k8sClient.deleteNamespace(namespace); }); + test.beforeEach(async ({ page }) => { + await warmupSPA(page); + }); + test('KN-05-TC04: Create knative workload from Git', async ({ page }) => { test.setTimeout(180_000); const addFlowPage = new AddFlowPage(page); From e9a83db166de98f727a52838d44d937203e5f0df Mon Sep 17 00:00:00 2001 From: logonoff Date: Mon, 10 Aug 2026 21:01:10 -0400 Subject: [PATCH 3/3] NO-JIRA: Fix i18n and eslint issues --- dynamic-demo-plugin/i18next.config.ts | 2 +- dynamic-demo-plugin/package.json | 3 +-- .../e2e/tests/knative/serverless/knative-ci.spec.ts | 8 ++++---- .../e2e/tests/webterminal/web-terminal-config.spec.ts | 8 ++++---- frontend/i18next.config.ts | 2 +- .../packages/console-app/locales/en/console-app.json | 6 ++++-- .../src/components/nodes/useCustomNodeActions.tsx | 11 +++++------ 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/dynamic-demo-plugin/i18next.config.ts b/dynamic-demo-plugin/i18next.config.ts index 3ec82dd3bf6..8548f366e0c 100644 --- a/dynamic-demo-plugin/i18next.config.ts +++ b/dynamic-demo-plugin/i18next.config.ts @@ -7,7 +7,7 @@ export default defineConfig({ input: 'src/**/*.{js,jsx,ts,tsx}', output: 'locales/{{language}}/{{namespace}}.json', - defaultValue: (key) => key, + defaultValue: (key) => key.replace(/_(?:one|other)$/, ''), sort: true, keySeparator: false, nsSeparator: '~', diff --git a/dynamic-demo-plugin/package.json b/dynamic-demo-plugin/package.json index 99d2c38e627..9f0c63e3d58 100644 --- a/dynamic-demo-plugin/package.json +++ b/dynamic-demo-plugin/package.json @@ -8,8 +8,7 @@ "build-rspack": "BUNDLER=rspack yarn ts-node node_modules/.bin/rspack -c webpack.config.ts", "build": "yarn clean && NODE_ENV=production yarn build-rspack && NODE_ENV=production yarn build-webpack", "build-dev": "yarn clean && yarn build-rspack && yarn build-webpack", - "build-plugin-sdk": "yarn --cwd ../frontend build-plugin-sdk && yarn install-plugin-sdk", - "install-plugin-sdk": "rm -rf node_modules/@openshift-console && yarn install", + "build-plugin-sdk": "yarn --cwd ../frontend/packages/console-dynamic-plugin-sdk build", "start-console": "./start-console.sh", "http-server": "./http-server.sh dist", "i18n": "i18next-cli lint && i18next-cli extract", diff --git a/frontend/e2e/tests/knative/serverless/knative-ci.spec.ts b/frontend/e2e/tests/knative/serverless/knative-ci.spec.ts index 567e1909dc5..82cf1dcb059 100644 --- a/frontend/e2e/tests/knative/serverless/knative-ci.spec.ts +++ b/frontend/e2e/tests/knative/serverless/knative-ci.spec.ts @@ -36,14 +36,14 @@ test.describe( } catch { /* ignore on OCP 4 */ } }); - test.afterAll(async () => { - await k8sClient.deleteNamespace(namespace); - }); - test.beforeEach(async ({ page }) => { await warmupSPA(page); }); + test.afterAll(async () => { + await k8sClient.deleteNamespace(namespace); + }); + test('KN-05-TC04: Create knative workload from Git', async ({ page }) => { test.setTimeout(180_000); const addFlowPage = new AddFlowPage(page); diff --git a/frontend/e2e/tests/webterminal/web-terminal-config.spec.ts b/frontend/e2e/tests/webterminal/web-terminal-config.spec.ts index 86b051e88d4..dd24603d1fa 100644 --- a/frontend/e2e/tests/webterminal/web-terminal-config.spec.ts +++ b/frontend/e2e/tests/webterminal/web-terminal-config.spec.ts @@ -16,14 +16,14 @@ test.describe('Customization of web terminal options', () => { await ensureWebTerminalOperatorInstalled(k8sClient); }); - test.afterAll(async ({ k8sClient }) => { - await uninstallWebTerminalOperator(k8sClient); - }); - test.beforeEach(async ({ page }) => { await warmupSPA(page); }); + test.afterAll(async ({ k8sClient }) => { + await uninstallWebTerminalOperator(k8sClient); + }); + test( 'navigate to Web Terminal Configuration page', async ({ page }) => { diff --git a/frontend/i18next.config.ts b/frontend/i18next.config.ts index 5f7a8696f6d..7b301d6144f 100644 --- a/frontend/i18next.config.ts +++ b/frontend/i18next.config.ts @@ -24,7 +24,7 @@ export default defineConfig({ ); }, - defaultValue: (key) => key, // namespace should not be included in the default value + defaultValue: (key) => key.replace(/_(?:one|other)$/, ''), sort: true, keySeparator: false, nsSeparator: '~', diff --git a/frontend/packages/console-app/locales/en/console-app.json b/frontend/packages/console-app/locales/en/console-app.json index 1c5f0e0abcd..fba59377747 100644 --- a/frontend/packages/console-app/locales/en/console-app.json +++ b/frontend/packages/console-app/locales/en/console-app.json @@ -68,8 +68,10 @@ "API Servers": "API Servers", "API version": "API version", "Applications": "Applications", - "Applies to {{nodeCount}} selected nodes that are currently unschedulable.": "Applies to {{nodeCount}} selected nodes that are currently unschedulable.", - "Applies to {{nodeCount}} selected nodes that are schedulable.": "Applies to {{nodeCount}} selected nodes that are schedulable.", + "Applies to {{count}} selected nodes that are currently unschedulable._one": "Applies to {{count}} selected node that is currently unschedulable.", + "Applies to {{count}} selected nodes that are currently unschedulable._other": "Applies to {{count}} selected nodes that are currently unschedulable.", + "Applies to {{count}} selected nodes that are schedulable._one": "Applies to {{count}} selected node that is schedulable.", + "Applies to {{count}} selected nodes that are schedulable._other": "Applies to {{count}} selected nodes that are schedulable.", "Approval required": "Approval required", "Approve": "Approve", "Architecture": "Architecture", diff --git a/frontend/packages/console-app/src/components/nodes/useCustomNodeActions.tsx b/frontend/packages/console-app/src/components/nodes/useCustomNodeActions.tsx index 091dfbbe88a..560125d6651 100644 --- a/frontend/packages/console-app/src/components/nodes/useCustomNodeActions.tsx +++ b/frontend/packages/console-app/src/components/nodes/useCustomNodeActions.tsx @@ -58,10 +58,9 @@ export const useCustomNodeActions = ({ onClick={handleMarkSchedulable} isDisabled={inProgress} data-test="bulk-mark-schedulable" - description={t( - 'Applies to {{nodeCount}} selected nodes that are currently unschedulable.', - { nodeCount: unschedulableCount }, - )} + description={t('Applies to {{count}} selected nodes that are currently unschedulable.', { + count: unschedulableCount, + })} > {t('Mark schedulable')} , @@ -75,8 +74,8 @@ export const useCustomNodeActions = ({ onClick={handleMarkUnschedulable} isDisabled={inProgress} data-test="bulk-mark-unschedulable" - description={t('Applies to {{nodeCount}} selected nodes that are schedulable.', { - nodeCount: schedulableCount, + description={t('Applies to {{count}} selected nodes that are schedulable.', { + count: schedulableCount, })} > {t('Mark unschedulable')}