Commonly changed configuration options:
- baseUrl: default
null
, change tohttp://localhost:8000
and use just relative URLs incy.visit("/en/...")
- defaultCommandTimeout: default
4000
(4s), increase to at least10000
(10s) for Kiwi.com 🐌 - numTestsKeptInMemory: default
50
, don't worry to increase to200
- watchForFileChanges: default
true
, set tofalse
to disable auto reloading on file save
In file: cypress/support/index.js
Cypress.on("fail", (err, runnable) => {
debugger // eslint-disable-line no-debugger
return err
})
In file: cypress/support/index.js
win.localStorage.debug = "cypress:*"
/node_modules/.bin/cypress run …
=>
DEBUG=cypress:* /node_modules/.bin/cypress run …
In current Kiwi.com Frontend pipeline, this line is located in gitlab-ci.yml
// TODO: Make more important and notice-able
Change from
`baseUrl: "http://localhost:8000"`
to ie.
`baseUrl: "https://www.kiwi.com"`
WebStorm has very useful Test overview window.
It's not compatible with Cypress by default, but it's compatible with Mocha – which Cypress uses under the hood. In order to make it work with Cypress, we need to create new Run/Debug Configuration.
- Search for action
Edit configurations...
and "open it" - Click on the
+
icon in the top-left (or presscmd+n
) - Select Mocha
- In
Name
field, typeCypress
- In
Extra Mocha options
, put--require @babel/register --require "cypress/cypress-mocha-mock.js"
- In
Test directory
, click on the directory icon in the right side of the text input - Navigate to the directory with frontend, navigate into
cypress
, navigate intointegration
, select Open - Check that in
Test directory
is something likePATH_TO_THE_PROJECT/cypress/integration
- Check
Include subdirectories
- Click on OK
- "Cypress" should appear in the top-right corner of WebStorm window
- Click on the play button next to it
cy.get("…").invoke("width").should("be.greaterThan", 100) // TODO: Verify
cy.get("…").its("clientWidth").should("be.greaterThan", 100)
// TODO
cy.get("…")
.then($el => {
if ($el.is(":visible")) {
cy.wrap($el).click() // TODO: Verify
}
})
Cypress.Commands.add("logout", () => {
return cy
.window()
.its("localStorage")
.invoke("removeItem", "token")
})
cy.visit("")
cy.get(".Loader").should("not.exist", { timeout: 15 * 1000 })
describe("Loops", () => {
configs.forEach(config => {
describe(`Currency: ${config.currency}`, () => {
it("…", () => {
cy.visit(`/?currency=${config.currency}`)
// …
})
})
})
})
cy
.window()
.then(win => {
expect(
win.reduxStore.getState().options.currency
).to.eq("czk")
})
cy.get("…").type("typing")
cy.get("…").type("slow.typing", { delay: 100 })
cy
.get("…")
.type("Typing")
.blur()
.should("have.class", "error")
.prev() // TODO: Test and explain
.should("have.attr", "style", "color: red;")
cy.fixture("image.jpg").then(file => {
cy.get("form input[type=file]").then(fileInput => {
const fileInputEl = fileInput.get(0)
const dataTransfer = new DataTransfer()
dataTransfer.items.add(new File([file], "image.jpg"))
fileInputEl.files = dataTransfer.files
})
})
// TODO: Double check if correct
Cypress.Commands.add("triggerHover", elements => {
function fireEvent(element, event) {
if (element.fireEvent) {
element.fireEvent(`on${event}`)
} else {
const evObj = document.createEvent("Events")
evObj.initEvent(event, true, false)
element.dispatchEvent(evObj)
}
}
elements.each((index, element) => { fireEvent(element, "mouseover") })
})
Sadly, right now there’s no better way than full-text search
→ you can open devtools, use debugger, profile etc.
💡 open devtools to see console errors & warnings (e.g. proptypes errors)
Run only specific file
cypress run --spec cypress/integration/booking/booking-misc-spec.js
# or whatever folder with tests
Run only specific test
https:// www.kiwi.com /us/content/manage/1234 ?something=true
|- protocol -| |- hostname -| |- path -| |- query --
let last = cy.createSnapshot('last') // » { name, htmlAttrs: {}, body: {} }
let lastBody = last.body.get() // » [$body]
Cypress.$autIframe.contents().find('body').remove()
Cypress.$autIframe.contents().find('html').append(lastBody)
Cypress.$autIframe.contents().find('body')
before() => {
cy.visit('/', {
onBeforeLoad(win) {
cy.spy(win.console, 'log').as('log')
)
it('logs message on startup', () => {
cy.get('@log').should('have.been.calledOnceWithExactly', 'rendering app')
)
// filter tests by title substring
Cypress.grep('hello world')
// run filtered tests 100 times
Cypress.grep('hello world', null, 100)
// filter tests by tag string
// in this case will run tests with tag @smoke OR @fast
Cypress.grep(null, '@smoke @fast')
// run tests tagged @smoke AND @fast
Cypress.grep(null, '@smoke+@fast')
// run tests with title containing "hello" and tag @smoke
Cypress.grep('hello', '@smoke')
// run tests with title containing "hello" and tag @smoke 10 times
Cypress.grep('hello', '@smoke', 10)
CYPRESS_grep='#stable' CYPRESS_burn=5 npx cypress run
Cypress.env() // 'CI', ...
it.only('adds numbers via aliases', () => {
cy.visit('public/index.html')
cy.get('[name=a]').invoke('val').then(parseIt).as('a')
cy.get('[name=b]').invoke('val').then(parseIt).as('b')
cy.get('#result')
.invoke('text')
.then(parseInt)
.as('result')
.then (function () {
expect(this.a + this.b).to.eq(this.result)
})
)
https://github.com/cypress-io/cypress-skip-test
if (isOn('windows') && isOn('localhost')) { /* ... */ }