-
Notifications
You must be signed in to change notification settings - Fork 213
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
test(radio): Change tests to react-testing-library and improve coverage #381
Changes from 27 commits
4533ba9
58b032d
1573fd9
ea56b0d
fb992c3
b8df3d0
c544833
e9ed794
71a588a
42a3cd0
6265720
568f2fa
3b0ddf6
3dfb60b
e4151d1
7d8b8ea
60efc8d
8f25acb
e5d8573
95f1380
94dab81
c4732d0
038174e
a6de8cd
3469ac6
17f4af2
92d1a57
a2dd012
b7c6a63
65d1e74
2c9f3e1
bf1d921
630cfe3
648876b
6fa683f
cad4b83
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
export const getByLabelText = (label: string) => | ||
function getByLabelText($container?: JQuery) { | ||
const $label = ($container || Cypress.$('body')).find(`label:contains(${label})`); | ||
|
||
if (!$label.length) { | ||
throw Error(`Could not find a label containing "${label}"`); | ||
} | ||
const id = $label.attr('for'); | ||
try { | ||
const $input = Cypress.$(`[id="${id}"]`); | ||
return $input; | ||
} catch (e) { | ||
throw Error(`Could not find an element labelled by "${label}`); | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
import * as dom from './dom'; | ||
import * as stories from './stories'; | ||
import * as modal from './modal'; | ||
|
||
export {modal, stories}; | ||
export {dom, modal, stories}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import * as h from '../helpers'; | ||
|
||
const getRadio = () => { | ||
return cy.get(`[type="radio"]`); | ||
}; | ||
|
||
describe('Radio', () => { | ||
before(() => { | ||
h.stories.visit(); | ||
}); | ||
|
||
context(`given the Default story is rendered`, () => { | ||
beforeEach(() => { | ||
h.stories.load('Components|Inputs/Radio/React/Left Label/Radio', story); | ||
}); | ||
|
||
it('should pass accessibility checks', () => { | ||
cy.checkA11y(); | ||
}); | ||
|
||
context('when clicked', () => { | ||
beforeEach(() => { | ||
cy.getByLabelText('E-mail').click(); | ||
}); | ||
|
||
it.only('should be checked', () => { | ||
getRadio().should('be.checked'); | ||
}); | ||
}); | ||
}); | ||
|
||
before(() => { | ||
h.stories.visit(); | ||
}); | ||
context(`given the 'Disabled' story is rendered`, () => { | ||
beforeEach(() => { | ||
h.stories.load('Components|Inputs/Radio/React/Left Label/Radio', 'Disabled'); | ||
}); | ||
|
||
it('should pass accessibility checks', () => { | ||
cy.checkA11y(); | ||
}); | ||
|
||
it('should be disabled', () => { | ||
getRadio().should('be.disabled'); | ||
}); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import * as h from '../helpers'; | ||
|
||
describe('Radio Group', () => { | ||
before(() => { | ||
h.stories.visit(); | ||
}); | ||
['Default', 'Alert', 'Error with Grow'].forEach(story => { | ||
context(`given the '${story}' story is rendered`, () => { | ||
beforeEach(() => { | ||
h.stories.load('Components|Inputs/Radio/React/Top Label/Radio Group', story); | ||
}); | ||
|
||
it('should pass accessibility checks', () => { | ||
cy.checkA11y(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Random point of discussion: it really bugs me how much of a black box this is. For example, Radio group labels need to be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I asked Accessibility this question a few months ago. They estimate What you describe should be specifications in our Cypress files. describe('given the Error story is rendered', () => {
it('should have a legend element', () => {
// get radio input
// .parents('legend').should('exist')
})
it('should have an aria-describedby linking to the input element', () => {
// find radio input and get id to check against the value of the `aria-describedby`
})
}) I think the test block description is misleading. It should say something like: it('should pass axe-core checks', () => { To clarify: |
||
}); | ||
|
||
context('when clicking one radio and then selecting another radio', () => { | ||
beforeEach(() => { | ||
cy.getByLabelText('E-mail').click(); | ||
cy.getByLabelText('Mail').click(); | ||
}); | ||
|
||
it('should one have one radio selected', () => { | ||
cy.getByLabelText('Mail').should('be.checked'); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,4 @@ import 'cypress-axe'; | |
import 'cypress-storybook/cypress'; | ||
|
||
import './commands'; | ||
import './query'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import * as dom from '../helpers/dom'; | ||
|
||
declare global { | ||
namespace Cypress { | ||
interface Chainable<Subject> { | ||
getByLabelText(label: string): Cypress.Chainable<JQuery>; | ||
} | ||
} | ||
} | ||
|
||
const createRetryableCommand = ( | ||
name: string, | ||
message: string, | ||
options, | ||
getValue: (...args: any[]) => any | ||
) => { | ||
Cypress._.defaults(options, { | ||
log: true, | ||
timeout: 4000, | ||
}); | ||
|
||
if (options.log) { | ||
options._log = Cypress.log({ | ||
message: [message], | ||
}); | ||
} | ||
|
||
const retryValue = () => { | ||
return Cypress.Promise.try(getValue).catch(err => { | ||
options.error = err; | ||
return (cy as any).retry(retryValue, options); | ||
}); | ||
}; | ||
|
||
const resolveValue = () => { | ||
return Cypress.Promise.try(retryValue).then(value => { | ||
return (cy as any).verifyUpcomingAssertions(value, options, { | ||
onRetry: resolveValue, | ||
}); | ||
}); | ||
}; | ||
|
||
return resolveValue().then(value => { | ||
options._log.set('$el', value); | ||
if (options._log) { | ||
options._log.snapshot().end(); | ||
} | ||
|
||
return value; | ||
}); | ||
}; | ||
|
||
Cypress.Commands.add( | ||
'getByLabelText', | ||
{prevSubject: ['optional', 'element']}, | ||
($container: JQuery | undefined, labelText: string, options = {}) => { | ||
return createRetryableCommand('getByLabelText', labelText, options, () => { | ||
return dom.getByLabelText(labelText)($container); | ||
}); | ||
} | ||
); | ||
|
||
// We'll be adding commands to this file similar to Cypress testing Library |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
{ | ||
"compilerOptions": { | ||
"types": ["cypress"] | ||
"types": ["cypress", "@types/testing-library__cypress"] | ||
mannycarrera4 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}, | ||
"strict": true, | ||
"include": ["**/*.ts"], | ||
"exclude": [] | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we worried that this doesn't account for wrapping labels?
i.e.