Skip to content

Commit

Permalink
improve testing (#1376)
Browse files Browse the repository at this point in the history
* improve testing

* improve testing
  • Loading branch information
hirsch88 committed Apr 10, 2024
1 parent 2dfccc8 commit c3b12e7
Show file tree
Hide file tree
Showing 14 changed files with 72 additions and 35 deletions.
1 change: 1 addition & 0 deletions .github/workflows/actions/setup/action.yml
Expand Up @@ -23,5 +23,6 @@ runs:
cache: 'npm'

- name: Update NPM registry path
continue-on-error: true
shell: bash
run: npm run registry
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -77,6 +77,7 @@ e2e/downloads
e2e/reg.json
e2e/cypress/snapshots/actual
e2e/cypress/snapshots/diff
e2e/cypress/snapshots/report.html
e2e/cypress/downloads

resources/data
Expand Down
4 changes: 2 additions & 2 deletions docs/public/assets/css/preview.css
Expand Up @@ -451,12 +451,12 @@ div.has-visible-overflow.sbdocs-preview,
div.has-visible-overflow > .docs-story,
div.has-visible-overflow > .docs-story > div:first-child {
overflow: visible !important;
z-index: 10 !important;
z-index: 9 !important;
}

div.has-visible-overflow > .docs-story > div:nth-child(2) {
bottom: 10px;
z-index: 10 !important;
z-index: 9 !important;
}

.support {
Expand Down
15 changes: 8 additions & 7 deletions e2e/cypress/support/commands.ts
Expand Up @@ -127,15 +127,16 @@ Cypress.Commands.add('spyEvent', { prevSubject: 'element' }, (subject, event: st
})

Cypress.Commands.add('shouldHaveEventDetail', { prevSubject: 'optional' }, (subject, value: any, time = 0) => {
Cypress.log({
$el: subject as any,
type: 'parent',
displayName: 'hasEventDetail',
message: value,
})
return cy.wrap(subject, { log: false }).then(event => {
const spy = event as any as sinon.SinonSpy
expect(spy.getCall(time).args[0].detail).deep.equal(value)
const detail = spy.getCall(time).args[0].detail
Cypress.log({
$el: subject as any,
type: 'parent',
displayName: 'hasEventDetail',
message: JSON.stringify(detail),
})
expect(detail).deep.equal(value)
}) as any
})

Expand Down
2 changes: 2 additions & 0 deletions e2e/cypress/support/lib/visuals/command.ts
Expand Up @@ -72,6 +72,8 @@ function addCompareSnapshotCommand(screenshotOptions?: ScreenshotOptions): void
return compareScreenshots(visualRegressionOptions)
case 'base':
return cy.task('updateSnapshot', visualRegressionOptions)
case 'dev':
return true
default:
throw new Error(
`The "type" environment variable is unknown.
Expand Down
2 changes: 1 addition & 1 deletion e2e/cypress/support/lib/visuals/plugin.ts
Expand Up @@ -8,7 +8,7 @@ import { adjustCanvas, parseImage } from './utils/image'
import { logger } from './utils/logger'

export type DiffOption = 'always' | 'fail' | 'never'
export type TypeOption = 'regression' | 'base'
export type TypeOption = 'regression' | 'base' | 'dev'

export type VisualRegressionOptions = {
/** kind of comparison that we are going to execute */
Expand Down
4 changes: 2 additions & 2 deletions e2e/project.json
Expand Up @@ -6,7 +6,7 @@
"executor": "nx:run-commands",
"dependsOn": [{ "projects": ["core"], "target": "build" }],
"options": {
"commands": ["npx nx run core:serve", "npx nx run e2e:serve"],
"command": "concurrently --prefix=\">\" --hide=\"1\" \"npx nx run core:serve\" \"npx nx run e2e:serve\"",
"parallel": true
}
},
Expand All @@ -15,7 +15,7 @@
"dependsOn": ["prepare"],
"options": {
"cwd": "{projectRoot}",
"command": "cypress open --browser chrome --env visualRegressionType=regression --config screenshotsFolder=cypress/snapshots/actual"
"command": "cypress open --browser chrome --env visualRegressionType=dev --config screenshotsFolder=cypress/snapshots/actual"
}
},
"prepare": {
Expand Down
10 changes: 8 additions & 2 deletions packages/core/project.json
Expand Up @@ -9,14 +9,20 @@
"dependsOn": ["^build"],
"options": {
"cwd": "{projectRoot}",
"command": "set BAL_DEVELOPMENT=true & stencil build --dev --serve --watch --port=4000"
"command": "stencil build --dev --serve --watch --port=4000",
"env": {
"BAL_DEVELOPMENT": "true"
}
}
},
"serve": {
"executor": "nx:run-commands",
"options": {
"cwd": "{projectRoot}",
"command": "set BAL_DEVELOPMENT=true & stencil build --serve --watch --port=3333"
"command": "stencil build --serve --watch --port=3333",
"env": {
"BAL_TESTING": "true"
}
}
},
"test-ui": {
Expand Down
7 changes: 5 additions & 2 deletions packages/core/stencil.config.ts
Expand Up @@ -70,6 +70,9 @@ export const config: Config = {
type: 'dist',
esmLoaderPath: '../loader',
},
/**
* Use this outputs for documentation and e2e testing
*/
...(!IS_BAL_DEVELOPMENT
? [
CustomDocumentationGenerator,
Expand All @@ -88,7 +91,7 @@ export const config: Config = {
: []),
{
type: 'www',
dir: 'www',
dir: IS_BAL_TESTING ? '../../e2e/generated/www' : 'www',
serviceWorker: false,
empty: true,
copy: [
Expand Down Expand Up @@ -126,7 +129,7 @@ export const config: Config = {
],
},
/**
* Skip those outputs for documentation releases on vercel
* Skip those outputs for documentation releases on vercel and for e2e testing
*/
...(!IS_BAL_DOCUMENTATION && !IS_BAL_TESTING
? [
Expand Down
4 changes: 3 additions & 1 deletion packages/testing/src/commands/custom/component.command.ts
Expand Up @@ -55,8 +55,10 @@ Cypress.Commands.add(
(subject, options?: Partial<Cypress.Timeoutable & Cypress.Loggable>) => {
cy.document({ log: false }).then(document => document.fonts.ready)

log('waitForComponents', '', subject, options)
const o = wrapOptions(options)
if (o.log) {
log('waitForComponents', '', subject, options)
}
return cy
.wrap(subject, o)
.then(($el: any) => areComponentsReady($el))
Expand Down
44 changes: 30 additions & 14 deletions packages/testing/src/commands/custom/get.command.ts
Expand Up @@ -3,9 +3,10 @@ import { log, wrapOptions, checkAriaLabel } from '../helpers'

Cypress.Commands.add('getByTestId', (testID, options?: Partial<Cypress.Loggable>) => {
const o = wrapOptions(options)
const element = cy.get(byTestId(testID), o).waitForComponents(o)
element.then(o, $el => log('getByTestId', testID, $el, options))
return element
return cy
.get(byTestId(testID), o)
.waitForComponents(o)
.then(o, $el => log('getByTestId', testID, $el, options))
})

Cypress.Commands.add('getDescribingElement', { prevSubject: ['element'] }, (subject, options) => {
Expand Down Expand Up @@ -41,15 +42,21 @@ Cypress.Commands.add('getByLabelText', { prevSubject: ['optional'] }, (subject,
.contains('label', labelText, o)
.invoke(o, 'attr', 'for')
.then(forAttributeValue => {
return cy.get(`input[id="${forAttributeValue}"], textarea[id="${forAttributeValue}"]`, o)
return cy.get(
`input[id="${forAttributeValue}"], textarea[id="${forAttributeValue}"], button[id="${forAttributeValue}"]`,
o,
)
})
.then(o, $el => log(!!subject ? '-getByLabelText' : 'getByLabelText', labelText, $el, options)) as any
} else {
return cy
.contains('label', labelText, o)
.invoke(o, 'attr', 'for')
.then(forAttributeValue => {
return cy.get(`input[id="${forAttributeValue}"], textarea[id="${forAttributeValue}"]`, o)
return cy.get(
`input[id="${forAttributeValue}"], textarea[id="${forAttributeValue}"], button[id="${forAttributeValue}"]`,
o,
)
})
.then(o, $el => log(!!subject ? '-getByLabelText' : 'getByLabelText', labelText, $el, options)) as any
}
Expand All @@ -60,15 +67,23 @@ Cypress.Commands.add(
{
prevSubject: ['optional'],
},
(subject, placeholder, options?: Partial<Cypress.Loggable>) => {
(subject, placeholder, options?: Partial<Cypress.Loggable>): any => {
const o = wrapOptions(options)

const element = subject
? cy
.wrap(subject, o)
.find(`input[placeholder="${placeholder}"], textarea[placeholder="${placeholder}"]`, o)
.find(
`input[placeholder="${placeholder}"], textarea[placeholder="${placeholder}"], [data-placeholder="${placeholder}"]`,
o,
)
.waitForComponents(o)
: cy
.get(
`input[placeholder="${placeholder}"], textarea[placeholder="${placeholder}"], [data-placeholder="${placeholder}"]`,
o,
)
.waitForComponents(o)
: cy.get(`input[placeholder="${placeholder}"], textarea[placeholder="${placeholder}"]`, o).waitForComponents(o)

element.then(o, $el => log(!!subject ? '-getByPlaceholder' : 'getByPlaceholder', placeholder, $el, options))
return element
Expand All @@ -80,7 +95,7 @@ Cypress.Commands.add(
{
prevSubject: ['optional'],
},
(subject, role, options) => {
(subject, role, options): any => {
const o = wrapOptions(options)

function findElements() {
Expand All @@ -104,11 +119,12 @@ Cypress.Commands.add(
const labeledElements = filterLabeling(visibleElements)

if (labeledElements.length > 0) {
const firstElement = cy.wrap(labeledElements[0]).waitForComponents()
firstElement.then(o, $el =>
log(!!subject ? '-getByRole' : 'getByRole', `${role} ${JSON.stringify(options)}`, $el, options),
)
return firstElement as any
return cy
.wrap(labeledElements[0], o)
.waitForComponents(o)
.then(o, $el =>
log(!!subject ? '-getByRole' : 'getByRole', `${role} ${JSON.stringify(options)}`, $el, options),
)
}

return subject
Expand Down
2 changes: 1 addition & 1 deletion packages/testing/src/commands/custom/get.types.ts
Expand Up @@ -42,7 +42,7 @@ declare namespace Cypress {
* Gets a element by the role
*/
getByRole(
role: 'button' | 'label',
role: 'button' | 'label' | 'option' | 'input',
options: Partial<GetByRoleOptions & Loggable & Timeoutable & Withinable & Shadow>,
): Chainable<JQuery>
}
Expand Down
8 changes: 5 additions & 3 deletions packages/testing/src/commands/helpers.ts
Expand Up @@ -110,7 +110,7 @@ export const wrapCommand = (
return (selector: string) => {
return cy
.wrapComponent(element as any, { log: false })
.waitForComponents()
.waitForComponents({ log: false })
.find(selector, { log: false })
.then($el => {
Cypress.log({
Expand All @@ -135,6 +135,7 @@ export const log = (displayName: string, message: any = '', $el: any, options?:
message,
})
}
return $el
}

export const areComponentsReady = ($el: any) => {
Expand All @@ -161,8 +162,9 @@ export function checkAriaLabel(element: HTMLElement, label: string | undefined |
if (label === undefined || label === null || label === '') {
return true
}
const text = Cypress.$(element).text().trim()
const ariaLabel = Cypress.$(element).attr('aria-label')
const title = Cypress.$(element).attr('title')
const text = Cypress.$(element).text().trim()
return text === label.trim() || ariaLabel === label.trim() || title === label.trim()
const value = Cypress.$(element).attr('value')
return [text, ariaLabel, title, value].includes(label.trim())
}
3 changes: 3 additions & 0 deletions test/angular/build.sh
Expand Up @@ -13,6 +13,9 @@ FULL_APP_DIR="base/${APP_DIR}/."
# The full path to the built application.
BUILD_APP_DIR="${APP_DIR}/"

# Clean the an existing app dir first
rm -rf $BUILD_APP_DIR

# First we need to copy the base application
cp -R $FULL_BASE_DIR $BUILD_APP_DIR

Expand Down

0 comments on commit c3b12e7

Please sign in to comment.