Improve Server Pro tests to use semantic selectors (#29790)
* Replace placeholders with labels * Add 'Close dialog' label to modal close button to distinguish from footer Close button * Add and translate heading on the not found page * Update textarea to have id matching label's for attribute Simplify test for template description textarea * Label PDF zoom level dropdown button * Improve test selectors to use semantic roles and accessible names GitOrigin-RevId: d215ddca30ddf844cfffbcf0e528a601b134d772
This commit is contained in:
@@ -5,7 +5,7 @@ block content
|
||||
.container
|
||||
.error-container
|
||||
.error-details
|
||||
p.error-status Not found
|
||||
h1.error-status #{translate("not_found")}
|
||||
p.error-description #{translate("cant_find_page")}
|
||||
p.error-actions
|
||||
a.error-btn(href='/') Home
|
||||
|
||||
@@ -280,6 +280,7 @@
|
||||
"clicking_delete_will_remove_sso_config_and_clear_saml_data": "",
|
||||
"clone_with_git": "",
|
||||
"close": "",
|
||||
"close_dialog": "",
|
||||
"clsi_maintenance": "",
|
||||
"clsi_unavailable": "",
|
||||
"code_check_failed": "",
|
||||
@@ -1272,6 +1273,7 @@
|
||||
"pdf_unavailable_for_download": "",
|
||||
"pdf_viewer": "",
|
||||
"pdf_viewer_error": "",
|
||||
"pdf_zoom_level": "",
|
||||
"pending_additional_licenses": "",
|
||||
"pending_addon_cancellation": "",
|
||||
"pending_invite": "",
|
||||
|
||||
@@ -75,6 +75,7 @@ function PdfZoomDropdown({
|
||||
id="pdf-zoom-dropdown"
|
||||
variant="link"
|
||||
className="pdf-toolbar-btn pdfjs-zoom-dropdown-button small"
|
||||
aria-label={t('pdf_zoom_level')}
|
||||
>
|
||||
{rawScaleToPercentage(rawScale)}
|
||||
</DropdownToggle>
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
} from 'react-bootstrap'
|
||||
import { ModalBodyProps } from 'react-bootstrap/ModalBody'
|
||||
import type { Options as FocusTrapOptions } from 'focus-trap'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
type OLModalProps = ModalProps & {
|
||||
size?: 'sm' | 'lg'
|
||||
@@ -52,8 +53,13 @@ export function OLModalHeader({
|
||||
closeButton = true,
|
||||
...props
|
||||
}: OLModalHeaderProps) {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<Modal.Header closeButton={closeButton} {...props}>
|
||||
<Modal.Header
|
||||
closeButton={closeButton}
|
||||
closeLabel={t('close_dialog')}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Modal.Header>
|
||||
)
|
||||
|
||||
@@ -357,6 +357,7 @@
|
||||
"clicking_delete_will_remove_sso_config_and_clear_saml_data": "Clicking <0>Delete</0> will remove your SSO configuration and unlink all users. You can only do this when SSO is disabled in your group settings.",
|
||||
"clone_with_git": "Clone with Git",
|
||||
"close": "Close",
|
||||
"close_dialog": "Close dialog",
|
||||
"clsi_maintenance": "The compile servers are down for maintenance, and will be back shortly.",
|
||||
"clsi_unavailable": "Sorry, the compile server for your project was temporarily unavailable. Please try again in a few moments.",
|
||||
"cn": "Chinese (Simplified)",
|
||||
@@ -1506,6 +1507,7 @@
|
||||
"normally_x_price_per_month": "Normally __price__ per month",
|
||||
"normally_x_price_per_year": "Normally __price__ per year",
|
||||
"not_a_student": "Not a student?",
|
||||
"not_found": "Not found",
|
||||
"not_found_error_from_the_supplied_url": "The link to open this content on Overleaf pointed to a file that could not be found. If this keeps happening for links on a particular site, please report this to them.",
|
||||
"not_managed": "Not managed",
|
||||
"not_now": "Not now",
|
||||
@@ -1659,6 +1661,7 @@
|
||||
"pdf_unavailable_for_download": "PDF unavailable for download",
|
||||
"pdf_viewer": "PDF Viewer",
|
||||
"pdf_viewer_error": "There was a problem displaying the PDF for this project.",
|
||||
"pdf_zoom_level": "PDF zoom level",
|
||||
"pending": "Pending",
|
||||
"pending_additional_licenses": "Your subscription is changing to include <0>__pendingAdditionalLicenses__</0> additional license(s) for a total of <1>__pendingTotalLicenses__</1> licenses.",
|
||||
"pending_addon_cancellation": "Your subscription will change to remove the <strong>__addOnName__</strong> add-on at the end of the current billing period.",
|
||||
|
||||
@@ -163,7 +163,7 @@ describe('<EditorLeftMenu />', function () {
|
||||
cy.findByRole('heading', { name: 'Copy project' })
|
||||
|
||||
// try closing & re-opening the modal with different methods
|
||||
cy.findByRole('button', { name: 'Close' }).click()
|
||||
cy.findByRole('button', { name: 'Close dialog' }).click()
|
||||
cy.findByRole('button', { name: 'Copy project' }).click()
|
||||
cy.findByRole('button', { name: 'Cancel' }).click()
|
||||
cy.findByRole('button', { name: 'Copy project' }).click()
|
||||
|
||||
@@ -43,7 +43,7 @@ describe('<OLModal />', function () {
|
||||
cy.findByRole('button', { name: 'Open modal' }).click()
|
||||
cy.findByRole('dialog').should('be.visible')
|
||||
cy.findByLabelText(/enter text/i).should('be.visible')
|
||||
cy.get('body').type('{esc}')
|
||||
cy.findByRole('button', { name: 'Close dialog' }).click()
|
||||
// Modal should hide with single escape (escapeDeactivates: false means FocusTrap doesn't handle it)
|
||||
cy.findByRole('dialog').should('not.exist')
|
||||
cy.findByRole('button', { name: 'Open modal' }).should('be.visible')
|
||||
@@ -70,13 +70,13 @@ describe('<OLModal />', function () {
|
||||
cy.findByRole('button', { name: 'Open modal' }).click()
|
||||
cy.findByRole('dialog').should('be.visible')
|
||||
|
||||
cy.findByRole('button', { name: 'Close' }).should('be.focused')
|
||||
cy.findByRole('button', { name: 'Close dialog' }).should('be.focused')
|
||||
cy.focused().tab()
|
||||
cy.findByLabelText(/enter text/i).should('be.focused')
|
||||
cy.focused().tab()
|
||||
cy.findByRole('button', { name: 'Close the modal' }).should('be.focused')
|
||||
cy.focused().tab()
|
||||
cy.findByRole('button', { name: 'Close' }).should('be.focused')
|
||||
cy.findByRole('button', { name: 'Close dialog' }).should('be.focused')
|
||||
cy.focused().tab({ shift: true })
|
||||
cy.findByRole('button', { name: 'Close the modal' }).should('be.focused')
|
||||
})
|
||||
@@ -95,7 +95,7 @@ describe('<OLModal />', function () {
|
||||
cy.mount(<Modal />)
|
||||
cy.findByRole('button', { name: 'Open modal' }).click()
|
||||
cy.findByRole('dialog').should('be.visible')
|
||||
cy.findByRole('button', { name: 'Close' }).click()
|
||||
cy.findByRole('button', { name: 'Close dialog' }).click()
|
||||
cy.findByRole('dialog').should('not.exist')
|
||||
})
|
||||
|
||||
@@ -103,7 +103,7 @@ describe('<OLModal />', function () {
|
||||
cy.mount(<Modal backdrop="static" />)
|
||||
cy.findByRole('button', { name: 'Open modal' }).click()
|
||||
cy.findByRole('dialog').should('be.visible')
|
||||
cy.get('body').type('{esc}')
|
||||
cy.findByRole('button', { name: 'Close dialog' }).click()
|
||||
cy.findByRole('dialog').should('not.exist')
|
||||
})
|
||||
})
|
||||
|
||||
+2
-2
@@ -24,8 +24,8 @@ describe('<SettingsDictionary />', function () {
|
||||
within(modal).getByRole('heading', { name: 'Edit Dictionary' })
|
||||
within(modal).getByText('Your custom dictionary is empty.')
|
||||
|
||||
const [, closeButton] = within(modal).getAllByRole('button', {
|
||||
name: 'Close',
|
||||
const closeButton = within(modal).getByRole('button', {
|
||||
name: 'Close dialog',
|
||||
})
|
||||
fireEvent.click(closeButton)
|
||||
expect(screen.getByTestId('dictionary-modal')).to.not.be.null
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@ describe('<NewProjectButton />', function () {
|
||||
|
||||
it('close the new project modal when clicking at the top right "x" button', function () {
|
||||
fireEvent.click(screen.getByRole('menuitem', { name: 'Blank project' }))
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Close' }))
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Close dialog' }))
|
||||
|
||||
expect(screen.queryByRole('dialog')).to.be.null
|
||||
})
|
||||
|
||||
+2
-2
@@ -26,8 +26,8 @@ describe('<DictionarySetting />', function () {
|
||||
within(modal).getByRole('heading', { name: 'Edit Dictionary' })
|
||||
within(modal).getByText('Your custom dictionary is empty.')
|
||||
|
||||
const [, closeButton] = within(modal).getAllByRole('button', {
|
||||
name: 'Close',
|
||||
const closeButton = within(modal).getByRole('button', {
|
||||
name: 'Close dialog',
|
||||
})
|
||||
fireEvent.click(closeButton)
|
||||
expect(screen.getByTestId('dictionary-modal')).to.not.be.null
|
||||
|
||||
@@ -35,7 +35,7 @@ describe('<LeaveSection />', function () {
|
||||
)
|
||||
|
||||
const cancelButton = screen.getByRole('button', {
|
||||
name: 'Close',
|
||||
name: 'Cancel',
|
||||
})
|
||||
|
||||
fireEvent.click(cancelButton)
|
||||
|
||||
+6
-11
@@ -141,15 +141,10 @@ describe('<ShareProjectModal/>', function () {
|
||||
createContextProps()
|
||||
)
|
||||
|
||||
const [headerCloseButton, footerCloseButton] = await screen.findAllByRole(
|
||||
'button',
|
||||
{ name: 'Close' }
|
||||
)
|
||||
const closeButton = screen.getByRole('button', { name: 'Close dialog' })
|
||||
await userEvent.click(closeButton)
|
||||
|
||||
await userEvent.click(headerCloseButton)
|
||||
await userEvent.click(footerCloseButton)
|
||||
|
||||
expect(handleHide.callCount).to.equal(2)
|
||||
expect(handleHide.callCount).to.equal(1)
|
||||
})
|
||||
|
||||
it('handles access level "private"', async function () {
|
||||
@@ -410,7 +405,7 @@ describe('<ShareProjectModal/>', function () {
|
||||
createContextProps({ publicAccessLevel: 'tokenBased', invites })
|
||||
)
|
||||
|
||||
const [, closeButton] = screen.getAllByRole('button', {
|
||||
const closeButton = screen.getByRole('button', {
|
||||
name: 'Close',
|
||||
})
|
||||
|
||||
@@ -446,7 +441,7 @@ describe('<ShareProjectModal/>', function () {
|
||||
createContextProps({ publicAccessLevel: 'tokenBased', invites })
|
||||
)
|
||||
|
||||
const [, closeButton] = screen.getAllByRole('button', {
|
||||
const closeButton = screen.getByRole('button', {
|
||||
name: 'Close',
|
||||
})
|
||||
|
||||
@@ -481,7 +476,7 @@ describe('<ShareProjectModal/>', function () {
|
||||
createContextProps({ publicAccessLevel: 'tokenBased', members })
|
||||
)
|
||||
|
||||
const [, closeButton] = screen.getAllByRole('button', {
|
||||
const closeButton = screen.getByRole('button', {
|
||||
name: 'Close',
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user