Files
jobtrackingapp/docs/redesign/phase-5/p5-15/p5-15-02/evidence/native-issues.json
T

233 lines
22 KiB
JSON
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"scope": "Native synthetic owned SQLite/browser evidence; no human AT/device acceptance",
"reports": [
{
"source": ".artifacts/p5-15-02/browser/audit-attempt3.json",
"sha256": "89af6297f09ad03072e5a617e0e4b0dd55cd8ebe1a8b310872525a8d1d81319d",
"stats": {
"startTime": "2026-10-10T18:25:41.491Z",
"duration": 197611.17,
"expected": 2,
"skipped": 0,
"unexpected": 4,
"flaky": 0
},
"tests": [
{
"name": "[P5-15-02] reduced-motion mobile drawer enters focus and Escape returns it",
"status": "failed",
"errorMessages": [
"Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: getByRole('dialog', { name: 'Navigation', exact: true }).getByRole('button', { name: 'Dashboard', exact: true })\nExpected: focused\nReceived: inactive\nTimeout: 5000ms\n\nCall log:\n\u001b[2m - Expect \"soft toBeFocused\" with timeout 5000ms\u001b[22m\n\u001b[2m - waiting for getByRole('dialog', { name: 'Navigation', exact: true }).getByRole('button', { name: 'Dashboard', exact: true })\u001b[22m\n\u001b[2m 12 × locator resolved to <div tabindex=\"0\" role=\"button\" aria-label=\"Dashboard\" class=\"MuiButtonBase-root MuiListItemButton-root MuiListItemButton-gutters MuiListItemButton-root MuiListItemButton-gutters css-j56oom\">…</div>\u001b[22m\n\u001b[2m - unexpected value \"inactive\"\u001b[22m\n\n\n 189 | await navigation.focus(); await navigation.press('Enter');\n 190 | const drawer = page.getByRole('dialog', { name: t.navigation, exact: true });\n> 191 | await expect.soft(drawer.getByRole('button', { name: t.dashboard, exact: true })).toBeFocused();\n | ^\n 192 | const focus = () => page.evaluate(() => ({ active: document.activeElement?.outerHTML.slice(0, 500), focusedInDialog: !!document.activeElement?.closest('[role=dialog]') }));\n 193 | const beforeScan = await focus();\n 194 | await collect(page, info, sample, 'navigation-open');\n at E:\\Storage\\Projects\\Active\\Job tracker\\job-tracker-ui\\e2e\\responsive-accessibility-audit.spec.ts:191:85",
"Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: getByRole('button', { name: 'Open navigation', exact: true })\nExpected: focused\nTimeout: 5000ms\nError: element(s) not found\n\nCall log:\n\u001b[2m - Expect \"soft toBeFocused\" with timeout 5000ms\u001b[22m\n\u001b[2m - waiting for getByRole('button', { name: 'Open navigation', exact: true })\u001b[22m\n\n\n 194 | await collect(page, info, sample, 'navigation-open');\n 195 | const afterScan = await focus();\n> 196 | await page.keyboard.press('Escape'); await expect.soft(navigation).toBeFocused();\n | ^\n 197 | const afterEscape = await focus();\n 198 | const stayedOpen = await drawer.isVisible();\n 199 | if (stayedOpen) {\n at E:\\Storage\\Projects\\Active\\Job tracker\\job-tracker-ui\\e2e\\responsive-accessibility-audit.spec.ts:196:70"
],
"observations": [
{
"name": "drawer-focus-recovery",
"value": {
"beforeScan": {
"active": "<button class=\"MuiButtonBase-root Mui-focusVisible MuiIconButton-root MuiIconButton-colorSecondary MuiIconButton-edgeStart MuiIconButton-sizeSmall css-1bif13m\" tabindex=\"0\" type=\"button\" aria-label=\"Open navigation\" aria-haspopup=\"dialog\" aria-expanded=\"true\"><svg class=\"MuiSvgIcon-root MuiSvgIcon-fontSizeSmall css-1pi2lzz\" focusable=\"false\" aria-hidden=\"true\" viewBox=\"0 0 24 24\"><path d=\"M3 18h18v-2H3zm0-5h18v-2H3zm0-7v2h18V6z\"></path></svg><span class=\"MuiTouchRipple-root css-4mb1j7\"><span cla",
"focusedInDialog": false
},
"afterScan": {
"active": "<button class=\"MuiButtonBase-root Mui-focusVisible MuiIconButton-root MuiIconButton-colorSecondary MuiIconButton-edgeStart MuiIconButton-sizeSmall css-1bif13m\" tabindex=\"0\" type=\"button\" aria-label=\"Open navigation\" aria-haspopup=\"dialog\" aria-expanded=\"true\"><svg class=\"MuiSvgIcon-root MuiSvgIcon-fontSizeSmall css-1pi2lzz\" focusable=\"false\" aria-hidden=\"true\" viewBox=\"0 0 24 24\"><path d=\"M3 18h18v-2H3zm0-5h18v-2H3zm0-7v2h18V6z\"></path></svg><span class=\"MuiTouchRipple-root css-4mb1j7\"><span cla",
"focusedInDialog": false
},
"afterEscape": {
"active": "<button class=\"MuiButtonBase-root Mui-focusVisible MuiIconButton-root MuiIconButton-colorSecondary MuiIconButton-edgeStart MuiIconButton-sizeSmall css-1bif13m\" tabindex=\"0\" type=\"button\" aria-label=\"Open navigation\" aria-haspopup=\"dialog\" aria-expanded=\"true\"><svg class=\"MuiSvgIcon-root MuiSvgIcon-fontSizeSmall css-1pi2lzz\" focusable=\"false\" aria-hidden=\"true\" viewBox=\"0 0 24 24\"><path d=\"M3 18h18v-2H3zm0-5h18v-2H3zm0-7v2h18V6z\"></path></svg><span class=\"MuiTouchRipple-root css-4mb1j7\"><span cla",
"focusedInDialog": false
},
"stayedOpen": true,
"afterTabAndEscape": {
"active": "<button class=\"MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedPrimary MuiButton-sizeSmall MuiButton-containedSizeSmall MuiButton-colorPrimary Mui-focusVisible MuiButtonGroup-grouped MuiButtonGroup-groupedHorizontal MuiButtonGroup-groupedOutlined MuiButtonGroup-groupedOutlinedHorizontal MuiButtonGroup-groupedOutlinedPrimary MuiButton-root MuiButton-contained MuiButton-containedPrimary MuiButton-sizeSmall MuiButton-containedSizeSmall MuiButton-colorPrimary MuiButtonGroup-",
"focusedInDialog": false
},
"drawerStillVisible": false,
"humanScreenReader": "NOT VERIFIED"
}
}
]
},
{
"name": "[P5-15-02 C06 C07] CV source action reaches the existing Career Profile workflow",
"status": "failed",
"errorMessages": [
"Error: \u001b[2mexpect(\u001b[22m\u001b[31mpage\u001b[39m\u001b[2m).\u001b[22mtoHaveURL\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m)\u001b[22m failed\n\nExpected: predicate to succeed\nReceived: \u001b[31m\"http://localhost:3300/career/profile\"\u001b[39m\nTimeout: 5000ms\n\n\n 272 | await expect(page.getByRole('main')).toBeVisible();\n 273 | await info.attach('cv-source-action-destination', { body: JSON.stringify({ href, destination: page.url(), expected: '/career or /career?section=profile; established canonical source workflow', observedText: await page.getByRole('main').innerText() }), contentType: 'application/json' });\n> 274 | await expect(page).toHaveURL(url => url.pathname === '/career');\n | ^\n 275 | await expect(page.getByLabel(t.profileCvContactFullName, { exact: true })).toHaveValue('Åse Revisjonseksempel');\n 276 | });\n 277 |\n at E:\\Storage\\Projects\\Active\\Job tracker\\job-tracker-ui\\e2e\\responsive-accessibility-audit.spec.ts:274:22"
],
"observations": [
{
"name": "cv-source-action-destination",
"value": {
"href": "/career/profile",
"destination": "http://localhost:3300/career/profile",
"expected": "/career or /career?section=profile; established canonical source workflow",
"observedText": "Home\n/\nCareer Workspace\n/\nCV Builder\nCV Builder\nThis CV only\nVersion 1\nSaved\nDownload PDF\nCV editing controls\nContent\nTemplate\nCustomize\nAI Tools\nHistory\nGo to section\n​\nGo to section\nGo To Preview\nCareer Profile is your source. Editing wording, order or inclusion here changes only this CV.\nOpen Career Profile\nHeadline override\nHeadline override\n\nBlank uses your Career Profile headline. Changes here affect only this CV.\n\nSections\nDrag to reorder, or use the arrows. Omitted content stays editable.\nAdd Content\nLive preview\nFit width · 68%\n1-page CV\nGo To Editor\nUse Page Up/Down to scroll. Tab moves into or out of the preview.\nPage 1 of 1"
}
}
]
},
{
"name": "[P5-15-02] emulated taps preserve CV modes and navigation across portrait/landscape viewport changes",
"status": "failed",
"errorMessages": [
"Error: \u001b[2mexpect(\u001b[22m\u001b[31mlocator\u001b[39m\u001b[2m).\u001b[22mtoBeFocused\u001b[2m(\u001b[22m\u001b[2m)\u001b[22m failed\n\nLocator: getByRole('button', { name: 'Åpne navigasjon', exact: true })\nExpected: focused\nTimeout: 5000ms\nError: element(s) not found\n\nCall log:\n\u001b[2m - Expect \"soft toBeFocused\" with timeout 5000ms\u001b[22m\n\u001b[2m - waiting for getByRole('button', { name: 'Åpne navigasjon', exact: true })\u001b[22m\n\n\n 299 | outcomes.push({ route: path, label, key: 'pointer comparison', opened: !!pointerChooser });\n 300 | if (pointerChooser) await pointerChooser.setFiles([]);\n> 301 | expect.soft(!!pointerChooser, `${label} pointer comparison opens the same picker`).toBe(true);\n | ^\n 302 | }\n 303 | }\n 304 | await info.attach('native-keyboard-file-chooser', { body: JSON.stringify({ outcomes, fileDataWritten: false }), contentType: 'application/json' });\n at E:\\Storage\\Projects\\Active\\Job tracker\\job-tracker-ui\\e2e\\responsive-accessibility-audit.spec.ts:301:72"
],
"observations": [
{
"name": "emulated-touch-boundary",
"value": {
"hasTouch": true,
"input": "Playwright Chromium touch tap",
"portraitLandscape": "CSS viewport changes, not physical orientation sensor",
"physicalTouch": "NOT VERIFIED",
"nativeTouchDrag": "NOT VERIFIED",
"softwareKeyboard": "NOT VERIFIED",
"cvUnchanged": true
}
}
]
}
]
},
{
"source": ".artifacts/p5-15-02/browser/audit-controls.json",
"sha256": "cc1e74867b5103ff214fd1355c3029a5f9027265bd978bacd5382574b7decb06",
"stats": {
"startTime": "2026-10-10T18:29:22.564Z",
"duration": 86727.949,
"expected": 1,
"skipped": 0,
"unexpected": 2,
"flaky": 0
},
"tests": [
{
"name": "[P5-15-02] keyboard command, dialog, section and document controls keep deliberate focus contracts",
"status": "passed",
"errorMessages": [],
"observations": [
{
"name": "native-keyboard-contracts",
"value": {
"commandEntryAndEscapeReturn": true,
"commandWorkflowDialog": true,
"workspaceArrowNavigation": true,
"cvKeyboardOrderPersisted": true,
"previewEntryScrollExit": true,
"evidence": "preceding hard assertions completed",
"humanScreenReader": "NOT VERIFIED"
}
}
]
},
{
"name": "[P5-15-02 C06 C07] CV source action reaches the existing Career Profile workflow",
"status": "failed",
"errorMessages": [
"Error: \u001b[2mexpect(\u001b[22m\u001b[31mpage\u001b[39m\u001b[2m).\u001b[22mtoHaveURL\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m)\u001b[22m failed\n\nExpected: predicate to succeed\nReceived: \u001b[31m\"http://localhost:3300/career/profile\"\u001b[39m\nTimeout: 5000ms\n\n\n 276 | await expect(page.getByRole('main')).toBeVisible();\n 277 | await info.attach('cv-source-action-destination', { body: JSON.stringify({ href, destination: page.url(), expected: '/career or /career?section=profile; established canonical source workflow', observedText: await page.getByRole('main').innerText() }), contentType: 'application/json' });\n> 278 | await expect(page).toHaveURL(url => url.pathname === '/career');\n | ^\n 279 | await expect(page.getByLabel(t.profileCvContactFullName, { exact: true })).toHaveValue('Åse Revisjonseksempel');\n 280 | });\n 281 |\n at E:\\Storage\\Projects\\Active\\Job tracker\\job-tracker-ui\\e2e\\responsive-accessibility-audit.spec.ts:278:22"
],
"observations": [
{
"name": "cv-source-action-destination",
"value": {
"href": "/career/profile",
"destination": "http://localhost:3300/career/profile",
"expected": "/career or /career?section=profile; established canonical source workflow",
"observedText": "Home\n/\nCareer Workspace\nCareer Workspace\n\n404\n\nPage not found\n\nThe page you were looking for does not exist or may have moved.\n\nGo Home\nGo Back"
}
}
]
},
{
"name": "[P5-15-02 W08 J10] keyboard upload and import controls open the native file chooser",
"status": "failed",
"errorMessages": [
"Error: Upload Enter opens the native picker\n\n\u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBe\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m) // Object.is equality\u001b[22m\n\nExpected: \u001b[32mtrue\u001b[39m\nReceived: \u001b[31mfalse\u001b[39m\n\n 298 | outcomes.push({ route: path, label, key, opened: !!chooser });\n 299 | if (chooser) await chooser.setFiles([]);\n> 300 | expect.soft(!!chooser, `${label} ${key} opens the native picker`).toBe(true);\n | ^\n 301 | }\n 302 | const [pointerChooser] = await Promise.all([page.waitForEvent('filechooser', { timeout: 3000 }).catch(() => null), control.click()]);\n 303 | outcomes.push({ route: path, label, key: 'pointer comparison', opened: !!pointerChooser });\n at E:\\Storage\\Projects\\Active\\Job tracker\\job-tracker-ui\\e2e\\responsive-accessibility-audit.spec.ts:300:75",
"Error: Upload Space opens the native picker\n\n\u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBe\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m) // Object.is equality\u001b[22m\n\nExpected: \u001b[32mtrue\u001b[39m\nReceived: \u001b[31mfalse\u001b[39m\n\n 298 | outcomes.push({ route: path, label, key, opened: !!chooser });\n 299 | if (chooser) await chooser.setFiles([]);\n> 300 | expect.soft(!!chooser, `${label} ${key} opens the native picker`).toBe(true);\n | ^\n 301 | }\n 302 | const [pointerChooser] = await Promise.all([page.waitForEvent('filechooser', { timeout: 3000 }).catch(() => null), control.click()]);\n 303 | outcomes.push({ route: path, label, key: 'pointer comparison', opened: !!pointerChooser });\n at E:\\Storage\\Projects\\Active\\Job tracker\\job-tracker-ui\\e2e\\responsive-accessibility-audit.spec.ts:300:75",
"Error: Import JSON Enter opens the native picker\n\n\u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBe\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m) // Object.is equality\u001b[22m\n\nExpected: \u001b[32mtrue\u001b[39m\nReceived: \u001b[31mfalse\u001b[39m\n\n 298 | outcomes.push({ route: path, label, key, opened: !!chooser });\n 299 | if (chooser) await chooser.setFiles([]);\n> 300 | expect.soft(!!chooser, `${label} ${key} opens the native picker`).toBe(true);\n | ^\n 301 | }\n 302 | const [pointerChooser] = await Promise.all([page.waitForEvent('filechooser', { timeout: 3000 }).catch(() => null), control.click()]);\n 303 | outcomes.push({ route: path, label, key: 'pointer comparison', opened: !!pointerChooser });\n at E:\\Storage\\Projects\\Active\\Job tracker\\job-tracker-ui\\e2e\\responsive-accessibility-audit.spec.ts:300:75",
"Error: Import JSON Space opens the native picker\n\n\u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBe\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m) // Object.is equality\u001b[22m\n\nExpected: \u001b[32mtrue\u001b[39m\nReceived: \u001b[31mfalse\u001b[39m\n\n 298 | outcomes.push({ route: path, label, key, opened: !!chooser });\n 299 | if (chooser) await chooser.setFiles([]);\n> 300 | expect.soft(!!chooser, `${label} ${key} opens the native picker`).toBe(true);\n | ^\n 301 | }\n 302 | const [pointerChooser] = await Promise.all([page.waitForEvent('filechooser', { timeout: 3000 }).catch(() => null), control.click()]);\n 303 | outcomes.push({ route: path, label, key: 'pointer comparison', opened: !!pointerChooser });\n at E:\\Storage\\Projects\\Active\\Job tracker\\job-tracker-ui\\e2e\\responsive-accessibility-audit.spec.ts:300:75",
"Error: Convert CSV to Import JSON Enter opens the native picker\n\n\u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBe\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m) // Object.is equality\u001b[22m\n\nExpected: \u001b[32mtrue\u001b[39m\nReceived: \u001b[31mfalse\u001b[39m\n\n 298 | outcomes.push({ route: path, label, key, opened: !!chooser });\n 299 | if (chooser) await chooser.setFiles([]);\n> 300 | expect.soft(!!chooser, `${label} ${key} opens the native picker`).toBe(true);\n | ^\n 301 | }\n 302 | const [pointerChooser] = await Promise.all([page.waitForEvent('filechooser', { timeout: 3000 }).catch(() => null), control.click()]);\n 303 | outcomes.push({ route: path, label, key: 'pointer comparison', opened: !!pointerChooser });\n at E:\\Storage\\Projects\\Active\\Job tracker\\job-tracker-ui\\e2e\\responsive-accessibility-audit.spec.ts:300:75",
"Error: Convert CSV to Import JSON Space opens the native picker\n\n\u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBe\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m) // Object.is equality\u001b[22m\n\nExpected: \u001b[32mtrue\u001b[39m\nReceived: \u001b[31mfalse\u001b[39m\n\n 298 | outcomes.push({ route: path, label, key, opened: !!chooser });\n 299 | if (chooser) await chooser.setFiles([]);\n> 300 | expect.soft(!!chooser, `${label} ${key} opens the native picker`).toBe(true);\n | ^\n 301 | }\n 302 | const [pointerChooser] = await Promise.all([page.waitForEvent('filechooser', { timeout: 3000 }).catch(() => null), control.click()]);\n 303 | outcomes.push({ route: path, label, key: 'pointer comparison', opened: !!pointerChooser });\n at E:\\Storage\\Projects\\Active\\Job tracker\\job-tracker-ui\\e2e\\responsive-accessibility-audit.spec.ts:300:75"
],
"observations": [
{
"name": "native-keyboard-file-chooser",
"value": {
"outcomes": [
{
"route": "/jobs/13?section=documents",
"label": "Upload",
"key": "Enter",
"opened": false
},
{
"route": "/jobs/13?section=documents",
"label": "Upload",
"key": "Space",
"opened": false
},
{
"route": "/jobs/13?section=documents",
"label": "Upload",
"key": "pointer comparison",
"opened": true
},
{
"route": "/settings",
"label": "Import JSON",
"key": "Enter",
"opened": false
},
{
"route": "/settings",
"label": "Import JSON",
"key": "Space",
"opened": false
},
{
"route": "/settings",
"label": "Import JSON",
"key": "pointer comparison",
"opened": true
},
{
"route": "/settings",
"label": "Convert CSV to Import JSON",
"key": "Enter",
"opened": false
},
{
"route": "/settings",
"label": "Convert CSV to Import JSON",
"key": "Space",
"opened": false
},
{
"route": "/settings",
"label": "Convert CSV to Import JSON",
"key": "pointer comparison",
"opened": true
}
],
"fileDataWritten": false
}
}
]
}
]
},
{
"source": ".artifacts/p5-15-02/browser/zoom.json",
"sha256": "ec2688b919aac5eade1613c94405d889dacd649cfa932e83f9faea748edc4e1a",
"stats": {
"startTime": "2026-10-10T18:22:11.787Z",
"duration": 43911.678,
"expected": 2,
"skipped": 0,
"unexpected": 0,
"flaky": 0
},
"tests": []
}
]
}