Skip to content

Commit

Permalink
misc: More accessibility fixes (#29322)
Browse files Browse the repository at this point in the history
* misc: Add tabindex to shiki code highlights so that it is accessible via the keyboard.

* Add tabindex for code preview in error-header

* Change h3 to h2 to meet a11y guidelines for incremental headers

* Add roles for landmarks

* Move navigation role to correct area

* Update main to have singular role

* update nav in banner to 'div' so there aren't 2 navs

* Have an h1 on the Global page to address a11y violation

* Fix aria-disabled attr to have valid 'true' value instead of 'disabled'

* Add changelog entry

* Fix tests that are looking for aria-disabled to now look for 'true'

* chore: fix test that's failing in npm/react test
  • Loading branch information
jennifer-shehane committed May 2, 2024
1 parent f629856 commit 1bb5a73
Show file tree
Hide file tree
Showing 23 changed files with 67 additions and 55 deletions.
4 changes: 4 additions & 0 deletions cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ _Released 5/7/2024 (PENDING)_

- We now pass the same default Chromium flags to Electron as we do to Chrome. As a result of this change, the application under test's `navigator.webdriver` property will now correctly be `true` when testing in Electron. Fixes [#27939](https://github.com/cypress-io/cypress/issues/27939).

**Misc:**

- Improved accessibility of the Cypress App in some areas. Addressed in [#29322](https://github.com/cypress-io/cypress/pull/29322).

**Dependency Updates:**

- Updated electron from `27.1.3` to `27.3.10` to address [CVE-2024-3156](https://nvd.nist.gov/vuln/detail/CVE-2024-3156). Addressed in [#29431](https://github.com/cypress-io/cypress/pull/29431).
Expand Down
2 changes: 1 addition & 1 deletion npm/react/cypress/component/basic/error-boundary.cy.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,6 @@ describe('Error Boundary', () => {
)

cy.get('header h1').should('contain', 'Something went wrong.')
cy.get('header h3').should('contain', 'ChildWithError failed to load')
cy.get('header h2').should('contain', 'ChildWithError failed to load')
})
})
2 changes: 1 addition & 1 deletion npm/react/cypress/component/basic/error-boundary.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export class ErrorBoundary extends React.Component {
<React.Fragment>
<header>
<h1>Something went wrong.</h1>
<h3>{`${name} failed to load`}</h3>
<h2>{`${name} failed to load`}</h2>
</header>
<section>
<pre>
Expand Down
4 changes: 2 additions & 2 deletions packages/app/cypress/e2e/cypress-in-cypress.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe('Cypress in Cypress', { viewportWidth: 1500, defaultCommandTimeout: 100
ctx.coreData.servers.cdpSocketServer?.emit('automation:disconnected')
})

cy.contains('h3', 'The Cypress extension has disconnected')
cy.contains('h2', 'The Cypress extension has disconnected')

cy.withCtx((ctx, { sinon }) => {
sinon.stub(ctx.actions.project, 'launchProject').resolves()
Expand Down Expand Up @@ -84,7 +84,7 @@ describe('Cypress in Cypress', { viewportWidth: 1500, defaultCommandTimeout: 100
connectedCallback(false)
})

cy.contains('h3', 'The Cypress extension is missing')
cy.contains('h2', 'The Cypress extension is missing')

// cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ describe('errorWarningChange subscription', () => {
})

function assertLoadingIntoErrorWorks (errorName: string) {
cy.contains('h3', errorName).should('be.visible')
cy.contains('h2', errorName).should('be.visible')
cy.contains('[role="alert"]', 'Loading').should('not.exist')
}

Expand Down Expand Up @@ -48,7 +48,7 @@ module.exports = {
})

it('shows expected error for malformed config file', () => {
cy.contains('h3', 'SyntaxError').should('not.exist')
cy.contains('h2', 'SyntaxError').should('not.exist')
cy.withCtx(async (ctx) => {
await ctx.actions.file.writeFileInProject('cypress.config.js',
`
Expand All @@ -75,7 +75,7 @@ module.exports = {
})

cy.contains(cy.i18n.launchpadErrors.generic.retryButton).click()
cy.contains('h3', 'SyntaxError').should('not.exist')
cy.contains('h2', 'SyntaxError').should('not.exist')
})
})
})
Expand Down
8 changes: 4 additions & 4 deletions packages/app/src/debug/DebugContainer.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ describe('<DebugContainer />', () => {
mountTestRun('allSkipped')

cy.findByTestId('collapsible').should('be.visible')
cy.contains('h3', 'Incomplete')
cy.contains('h2', 'Incomplete')
cy.contains('The browser server never connected.').should('be.visible')
cy.contains('2 of 3 specs skipped').should('be.visible')
})
Expand All @@ -181,7 +181,7 @@ describe('<DebugContainer />', () => {
mountTestRun('noTests')

cy.findByTestId('collapsible').should('be.visible')
cy.contains('h3', 'Incomplete')
cy.contains('h2', 'Incomplete')
cy.contains('Run has no tests').should('be.visible')
})
})
Expand All @@ -191,7 +191,7 @@ describe('<DebugContainer />', () => {
mountTestRun('timedOutWithCi')

cy.findByTestId('collapsible').should('be.visible')
cy.contains('h3', 'Incomplete')
cy.contains('h2', 'Incomplete')
cy.contains('Circle CI #1234').should('have.attr', 'href', 'https://circleci.com').should('be.visible')
cy.contains('Archive this run to remove it').should('be.visible')
})
Expand All @@ -200,7 +200,7 @@ describe('<DebugContainer />', () => {
mountTestRun('timedOutWithoutCi')

cy.findByTestId('collapsible').should('be.visible')
cy.contains('h3', 'Incomplete')
cy.contains('h2', 'Incomplete')
cy.contains('Circle CI #1234').should('not.exist')
cy.contains('Archive this run to remove it').should('be.visible')
})
Expand Down
12 changes: 6 additions & 6 deletions packages/app/src/debug/DebugRunStates.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ describe('Debug page states', () => {
cy.mount(<DebugErrored errors={[mockError]} totalSkippedSpecs={1} totalSpecs={1} />)

cy.findByTestId('collapsible').should('be.visible')
cy.get('h3').contains('Incomplete')
cy.get('h2').contains('Incomplete')
cy.contains(mockError)
cy.contains('1 of 1 spec skipped').should('be.visible')
})
Expand All @@ -46,7 +46,7 @@ describe('Debug page states', () => {
cy.mount(<DebugErrored errors={[mockError]} totalSkippedSpecs={4} totalSpecs={50} />)

cy.findByTestId('collapsible').should('be.visible')
cy.get('h3').contains('Incomplete')
cy.get('h2').contains('Incomplete')
cy.contains(mockError)
cy.contains('4 of 50 specs skipped').should('be.visible')
})
Expand All @@ -57,7 +57,7 @@ describe('Debug page states', () => {
cy.mount(<DebugNoTests />)

cy.findByTestId('collapsible').should('be.visible')
cy.get('h3').contains('Incomplete')
cy.get('h2').contains('Incomplete')
cy.contains('Run has no tests')
})
})
Expand All @@ -67,7 +67,7 @@ describe('Debug page states', () => {
cy.mount(<DebugTimedout totalSkippedSpecs={4} totalSpecs={50} />)

cy.findByTestId('collapsible').should('be.visible')
cy.get('h3').contains('Incomplete')
cy.get('h2').contains('Incomplete')
cy.contains('The run started but never completed. This can happen when the run is cancelled from CI or when Cypress crashes while running tests. Archive this run to remove it from the runs list and analytics.')
cy.contains('4 of 50 specs skipped')
})
Expand All @@ -77,7 +77,7 @@ describe('Debug page states', () => {
ci={{ id: '123', url: 'https://circleci.com/', formattedProvider: 'CircleCI', ciBuildNumberFormatted: '12345' }} totalSkippedSpecs={4} totalSpecs={50} />)

cy.findByTestId('collapsible').should('be.visible')
cy.get('h3').contains('Incomplete')
cy.get('h2').contains('Incomplete')
cy.contains('The run started but never completed. This can happen when the run is cancelled from CI or when Cypress crashes while running tests. Check your CircleCI #12345 logs for more information. Archive this run to remove it from the runs list and analytics.')
cy.findByTestId('external').contains('CircleCI #12345').should('have.attr', 'href', 'https://circleci.com/')
cy.contains('4 of 50 specs skipped')
Expand Down Expand Up @@ -189,7 +189,7 @@ describe('Debug page states', () => {
it('renders', () => {
cy.mount(<DebugCancelledAlert totalSpecs={5} totalSkippedSpecs={2} cancellation={{ cancelledAt: '2019-01-25T02:00:00.000Z', cancelledBy: { email: 'adams@cypress.io', fullName: 'Test Tester' } }} />)
cy.findByTestId('collapsible').should('be.visible')
cy.get('h3').contains('Manually cancelled')
cy.get('h2').contains('Manually cancelled')
cy.contains('2 of 5 specs skipped')
cy.findByTestId('cancelled-by-user-avatar').should('have.attr', 'style', 'background-image: url("https://s.gravatar.com/avatar/402f6cafb6c02371c2c23c5215ae3d85?size=48&default=mm");')
cy.contains('Test Tester')
Expand Down
4 changes: 2 additions & 2 deletions packages/app/src/debug/DebugSpec.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ describe('Run Failures button', () => {
))

cy.findByTestId('run-failures')
.should('have.attr', 'aria-disabled', 'disabled')
.should('have.attr', 'aria-disabled', 'true')
.should('not.have.attr', 'href')

cy.findByTestId('run-failures').realHover()
Expand All @@ -517,7 +517,7 @@ describe('Run Failures button', () => {
))

cy.findByTestId('run-failures')
.should('have.attr', 'aria-disabled', 'disabled')
.should('have.attr', 'aria-disabled', 'true')
.should('not.have.attr', 'href')

cy.findByTestId('run-failures').realHover()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ describe('AutomationDisconnected', () => {
cy.mount(<AutomationDisconnected />)

cy.findByTestId('collapsible').should('be.visible')
cy.contains('h3', 'The Cypress extension has disconnected.')
cy.contains('h2', 'The Cypress extension has disconnected.')
cy.contains('p', 'Cypress cannot run tests without this extension.')
cy.get('a').contains('Read more about browser management').should('have.attr', 'href', 'https://on.cypress.io/launching-browsers')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe('AutomationMissing', () => {
})

cy.findByTestId('collapsible').should('be.visible')
cy.contains('h3', 'The Cypress extension is missing.')
cy.contains('h2', 'The Cypress extension is missing.')
cy.contains('p', 'Cypress cannot run tests without this extension. Please choose another browser.')
cy.findByTestId('external').contains('Read more about browser management').should('have.attr', 'href', 'https://on.cypress.io/launching-browsers')

Expand Down
8 changes: 4 additions & 4 deletions packages/app/src/runs/RunsContainer.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ describe('<RunsContainer />', { keystrokeDelay: 0 }, () => {
},
})

cy.get('h3').contains(defaultMessages.runs.empty.gitRepositoryNotDetected)
cy.get('h2').contains(defaultMessages.runs.empty.gitRepositoryNotDetected)
cy.contains(defaultMessages.runs.empty.ensureGitSetupCorrectly)
})

Expand All @@ -146,7 +146,7 @@ describe('<RunsContainer />', { keystrokeDelay: 0 }, () => {
},
})

cy.get('h3').contains(defaultMessages.runs.empty.gitRepositoryNotDetected)
cy.get('h2').contains(defaultMessages.runs.empty.gitRepositoryNotDetected)
cy.contains(defaultMessages.runs.empty.ensureGitSetupCorrectly)
cy.get('[data-cy=alert-suffix-icon]').click()
cy.get('[data-cy=alert-header]').should('not.exist')
Expand Down Expand Up @@ -175,7 +175,7 @@ describe('<RunsContainer />', { keystrokeDelay: 0 }, () => {
},
})

cy.get('h3').contains(defaultMessages.runs.empty.noRunsFoundForBranch)
cy.get('h2').contains(defaultMessages.runs.empty.noRunsFoundForBranch)
cy.get('p').contains(defaultMessages.runs.empty.noRunsForBranchMessage)
// The utm_source will be Binary%3A+App in production`open` mode but we assert using Binary%3A+Launchpad as this is the value in CI
cy.contains(defaultMessages.links.learnMoreButton).should('have.attr', 'href', 'https://on.cypress.io/git-info?utm_source=Binary%3A+Launchpad&utm_medium=Runs+Tab&utm_campaign=No+Runs+Found')
Expand All @@ -202,7 +202,7 @@ describe('<RunsContainer />', { keystrokeDelay: 0 }, () => {
},
})

cy.get('h3').contains(defaultMessages.runs.empty.noRunsFoundForBranch)
cy.get('h2').contains(defaultMessages.runs.empty.noRunsFoundForBranch)
cy.get('p').contains(defaultMessages.runs.empty.noRunsForBranchMessage)
// The utm_source will be Binary%3A+App in production`open` mode but we assert using Binary%3A+Launchpad as this is the value in CI
cy.contains(defaultMessages.links.learnMoreButton).should('have.attr', 'href', 'https://on.cypress.io/git-info?utm_source=Binary%3A+Launchpad&utm_medium=Runs+Tab&utm_campaign=No+Runs+Found')
Expand Down
4 changes: 2 additions & 2 deletions packages/frontend-shared/src/components/AlertHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
:class="prefixIconClass"
/>
</slot>
<h3
<h2
class="grow font-medium text-left leading-normal decoration-current"
:class="headerClass"
>
<slot name="title">
{{ title }}
</slot>
</h3>
</h2>
<div class="relative shrink">
<slot
name="suffixIcon"
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend-shared/src/components/Button.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ describe('<Button />', { viewportWidth: 300, viewportHeight: 400 }, () => {
))

cy.contains('a', 'test').should('not.have.attr', 'href')
cy.contains('a', 'test').should('have.attr', 'aria-disabled', 'disabled')
cy.contains('a', 'test').should('have.attr', 'aria-disabled', 'true')
cy.contains('a', 'test').should('have.attr', 'role', 'link')
})

Expand Down
2 changes: 1 addition & 1 deletion packages/frontend-shared/src/components/Button.vue
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ const linkProps = computed(() => {
if (props.disabled) {
return {
role: 'link',
ariaDisabled: 'disabled',
ariaDisabled: 'true',
href: null,
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/frontend-shared/src/components/ShikiHighlight.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ shikiWrapperClasses computed property.
<div
v-if="highlighterInitialized"
ref="codeEl"
tabindex="0"
:class="[
'shiki-wrapper',
Expand Down
12 changes: 8 additions & 4 deletions packages/frontend-shared/src/gql-components/HeaderBarContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@
<div
v-else
class="flex font-medium text-gray-700 items-center children:leading-[24px]"
role="banner"
>
<img
class="h-[32px] mr-[18px] w-[32px]"
src="../assets/logos/cypress-dark.png"
alt="cypress"
>
<nav>
<div>
<ol>
<li
v-if="props.gql.isGlobalMode"
Expand Down Expand Up @@ -84,9 +85,12 @@
</template>
</template>
</ol>
</nav>
</div>
</div>
<div class="flex gap-6">
<nav
class="flex gap-6"
role="navigation"
>
<TopNav
:gql="props.gql"
:show-browsers="props.showBrowsers"
Expand Down Expand Up @@ -152,7 +156,7 @@
<span class="font-medium whitespace-nowrap group-hocus:text-indigo-500">{{ t('topNav.login.actionLogin') }}</span>
</button>
</div>
</div>
</nav>
</div>
</div>
</template>
Expand Down

5 comments on commit 1bb5a73

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 1bb5a73 May 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux x64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.9.0/linux-x64/develop-1bb5a7301ef9e1b2158eb8f3517483f0d53e8bee/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 1bb5a73 May 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux arm64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.9.0/linux-arm64/develop-1bb5a7301ef9e1b2158eb8f3517483f0d53e8bee/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 1bb5a73 May 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the win32 x64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.9.0/win32-x64/develop-1bb5a7301ef9e1b2158eb8f3517483f0d53e8bee/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 1bb5a73 May 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the darwin arm64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.9.0/darwin-arm64/develop-1bb5a7301ef9e1b2158eb8f3517483f0d53e8bee/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 1bb5a73 May 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the darwin x64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.9.0/darwin-x64/develop-1bb5a7301ef9e1b2158eb8f3517483f0d53e8bee/cypress.tgz

Please sign in to comment.