Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

misc: More accessibility fixes #29322

Merged
merged 17 commits into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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