From b131e36fb8d6e9770e557bb17fd0645aebe49200 Mon Sep 17 00:00:00 2001 From: cmorten Date: Mon, 22 Jun 2026 19:43:09 +0100 Subject: [PATCH 1/2] fix: lower case tab, window, and app names for safer matching --- src/nvdaTest.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/nvdaTest.ts b/src/nvdaTest.ts index 1a4a8e0..c379dbd 100644 --- a/src/nvdaTest.ts +++ b/src/nvdaTest.ts @@ -81,7 +81,9 @@ const focusBrowser = async ({ pageTitle: string; }) => { await nvdaPlaywright.perform(nvdaPlaywright.keyboardCommands.reportTitle); - let windowTitle = await nvdaPlaywright.lastSpokenPhrase(); + let windowTitle = (await nvdaPlaywright.lastSpokenPhrase()).toLowerCase(); + + console.log({ applicationName, pageTitle, windowTitle }); if (hasFocus({ applicationName, pageTitle, windowTitle })) { return; @@ -94,7 +96,7 @@ const focusBrowser = async ({ await nvdaPlaywright.perform(SWITCH_APPLICATION); await nvdaPlaywright.perform(nvdaPlaywright.keyboardCommands.reportTitle); - windowTitle = await nvdaPlaywright.lastSpokenPhrase(); + windowTitle = (await nvdaPlaywright.lastSpokenPhrase()).toLowerCase(); if (hasFocus({ applicationName, pageTitle, windowTitle })) { break; @@ -161,7 +163,10 @@ export const nvdaTest = test.extend<{ const pageTitle = await page.title(); // Ensure application is brought to front and focused. - await focusBrowser({ applicationName, pageTitle }); + await focusBrowser({ + applicationName: applicationName.toLowerCase(), + pageTitle: pageTitle.toLowerCase(), + }); // Ensure the document is ready and focused. await page.bringToFront(); From 89dd67c9795b9504df4a6beecb7277b47ffa61e4 Mon Sep 17 00:00:00 2001 From: cmorten Date: Mon, 22 Jun 2026 20:38:11 +0100 Subject: [PATCH 2/2] feat: implement string cleaning based on NVDA punctuation ignore rules for when matching nvda window announcement to current tab title --- src/nvdaTest.ts | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/nvdaTest.ts b/src/nvdaTest.ts index c379dbd..74b82da 100644 --- a/src/nvdaTest.ts +++ b/src/nvdaTest.ts @@ -62,14 +62,27 @@ type FocusBrowserParams = { pageTitle: string; }; +const cleanString = (str: string): string => + str + .toLowerCase() + // REF: https://github.com/nvaccess/nvda/blob/master/source/locale/en/symbols.dic + .replace(/[|¦:;'"`\-‐–—·_()[\]{}\\^~]/g, " ") + .replace(/\s+/g, " ") + .trim(); + const hasFocus = ({ applicationName, pageTitle, windowTitle, }: FocusBrowserParams & { windowTitle: string }) => { + const cleanedApplicationName = cleanString(applicationName); + const cleanedPageTitle = cleanString(pageTitle); + const cleanedWindowTitle = cleanString(windowTitle); + return ( - (pageTitle.length && windowTitle.startsWith(pageTitle)) || - windowTitle.includes(applicationName) + (cleanedPageTitle.length && + cleanedWindowTitle.startsWith(cleanedPageTitle)) || + cleanedWindowTitle.includes(cleanedApplicationName) ); }; @@ -81,9 +94,7 @@ const focusBrowser = async ({ pageTitle: string; }) => { await nvdaPlaywright.perform(nvdaPlaywright.keyboardCommands.reportTitle); - let windowTitle = (await nvdaPlaywright.lastSpokenPhrase()).toLowerCase(); - - console.log({ applicationName, pageTitle, windowTitle }); + let windowTitle = await nvdaPlaywright.lastSpokenPhrase(); if (hasFocus({ applicationName, pageTitle, windowTitle })) { return; @@ -96,7 +107,7 @@ const focusBrowser = async ({ await nvdaPlaywright.perform(SWITCH_APPLICATION); await nvdaPlaywright.perform(nvdaPlaywright.keyboardCommands.reportTitle); - windowTitle = (await nvdaPlaywright.lastSpokenPhrase()).toLowerCase(); + windowTitle = await nvdaPlaywright.lastSpokenPhrase(); if (hasFocus({ applicationName, pageTitle, windowTitle })) { break; @@ -164,8 +175,8 @@ export const nvdaTest = test.extend<{ const pageTitle = await page.title(); // Ensure application is brought to front and focused. await focusBrowser({ - applicationName: applicationName.toLowerCase(), - pageTitle: pageTitle.toLowerCase(), + applicationName, + pageTitle, }); // Ensure the document is ready and focused.