cypress-io / cypress Goto Github PK
View Code? Open in Web Editor NEWFast, easy and reliable testing for anything that runs in a browser.
Home Page: https://cypress.io
License: MIT License
Fast, easy and reliable testing for anything that runs in a browser.
Home Page: https://cypress.io
License: MIT License
If there are multiple chained actions associated to the same input, a change
event should not be triggered until the input loses focus.
Example Code
it "patches on change of input", ->
cy
.route("PATCH", /^\/answers\/\d+/, @answer).as("patchAnswer")
.get("@valueInput").clear().type("56").blur()
.wait("@patchAnswer").then (xhr) ->
expect(xhr.requestJSON).to.have.property("value", "56")
The .clear()
and the .type("56").blur()
are both triggering change
events. My test ends up patching value: ""
so that my test falsely fails. There should only be 1 change
event triggered when the input loses focus on .blur()
.
When I use cy.contains()
and pass in an option:
Example Code
cy .get("#dialog").within ->
cy.contains "1 question", exist: false
cy.contains "4 questions"
cy.contains "1 question"
The DOM input event should be fired when the value of an <input>
or <textarea>
element is changed through cy.type()
.
For IE9 < support, the propertychange
event should be fired when value of an <input>
or <textarea>
element is changed through cy.type()
.
I've defined a cy.fixture("form")
. My form.json file used to look like this:
{
"item": {
"id": 129083,
"instructions": "Inspect equipment to see what their condition is and repair any conditions found.",
"note": "All equipment seen on site.",
"requiresAsset": false
}
But cypress has reformatted my JSON file to look like below, removing all of the spacing in my values. You should not be doing any formatting on any values in a key:value pair.
{
"item": {
"id": 129083,
"instructions": "Inspectequipmenttoseewhattheirconditionisandrepairanyconditionsfound.",
"note": "Allequipmentseenonsite.",
"requiresAsset": false
}
I want to be able to test my application's behavior of updating the url on a user's click of the back button within their browser. I'd like to be able to have a way to do this in cypress commands.
I would like to be able to drag the cypress icon to a different position on the menu bar (because I have too many already and my screen is too small sometimes.)
Many applications (especially built-in ones from Apple) allow you to Cmd+Click+Drag to re-organize. I noticed that Cypress does not support this, but thought it might be a trivial bit of polish to drop in.
I have a few tests back to back that all use the spy
command. The first test displays all of the spies in the command log, but the subsequent tests do not display the spies in the command log.
Example Code
describe "triggerMethod", ->
before ->
@agents = cy.agents()
## removed code for brevity
@trigger = @agents.spy(@view, "trigger")
it "triggers methods on show", ->
App.mainRegion.show(@view)
events = _(@trigger.getCalls()).map (call) -> call.args[0]
expect(events).to.deep.eq(
["onBeforeRender", "before:render", "onRender", "render", "onBeforeShow", "before:show", "onBeforeAttach", "before:attach", "onAttach", "attach", "onShow", "show", "onDomRefresh", "dom:refresh"]
)
it "triggers methods on render", ->
@view.render()
events = _(@trigger.getCalls()).map (call) -> call.args[0]
expect(events).to.deep.eq(
["onBeforeRender", "before:render", "onRender", "render"]
)
it "triggers methods on destroy", ->
@view.destroy()
events = _(@trigger.getCalls()).map (call) -> call.args[0]
expect(events).to.deep.eq(
["onBeforeDestroy", "before:destroy", "onDestroy", "destroy"]
)
I'd like to be able to alias things other than DOM elements, for example a url string of a request. example:
describe "asset search", ->
beforeEach ->
cy
.route(/assets/, {}).as("getAssets")
.get("form").submit()
.wait("@getAssets").its("url").as("requestUrl")
it "does not search areaId", ->
cy.get("@requestUrl").should("not.match", /areaId/)
it "does not search locationId", ->
cy.get("@requestUrl").should("not.match", /locationId/)
This currently just says Syntax error, unrecognized expression: @requestUrl
When I use the command cy.type()
on a DOM element of input[type='number']
the text entered prepends to any existing value in the input instead of appending (as cy.type()
does on input[type='text']
and textarea
.
Example
<input name="height" type="number" value="25">
cy.get("input[name='height']").type("167").should("have.value", "25167")
This example's assertion will fail and say expected input to have value of '25167', but got '16725'
When I switch browser tabs while running cypress tests during cy.route() commands, the test suite fails and throws: Error: INVALID_STATE_ERR - 0
.
The stack trace leads to Sinon.js setResponseHeaders
method:
function verifyRequestOpened(xhr) {
if (xhr.readyState != FakeXMLHttpRequest.OPENED) {
throw new Error("INVALID_STATE_ERR - " + xhr.readyState);
}
}
When getting a collection of checkboxes, if I pass a length
option, this error is thrown:
Error: the domexception "InvalidStateError: Failed to read the 'selectionStart' property from
'HTMLInputElement': The input element's type ('radio') does not support selection."
Example Code
it "has teams checked", ->
cy.get(".teams-component").find(":checked", {length: 2})
If I have more than 1 form in the DOM and write:
cy.get("form").submit()
It will issue a form submit to all forms in the DOM. This is contrary to what would actually happen during user interaction.
Recommendation:
.submit()
command.cy.confirm()
command.cy.confirm
accept / cancel should log out in the commands UI.If multiple tests are being run and I happen to hover over the commands UI (which triggers reverting the DOM), it has the potential to affect the currently running tests (in that my current test cannot find the elements it should from the reverted DOM).
Prevent reverting the DOM if there are currently running tests.
Also: There could be a potential for affecting currently running tests with interaction in the iframe. Suggest also preventing interaction in the iframe if tests are currently running.
If I have cy.server
with respond: false
option, then have a cy.route()
with an option of respond: true
, the route does not properly respond.
Example
cy.server({
respond: false
}).route({
method: "PATCH",
url: /forms/,
response: {},
respond: true
});
I have this directory structure:
...and this is my cypress.json:
{
"cypress": {
...
"testFolder": "spec/cypress",
"javascripts": ["support/spec_helper.coffee"]
}
}
That javascripts
line makes it hit this URL:
http://localhost:3000/support/spec_helper.coffee
...which 404s. I think it is supposed to be hitting this one:
http://localhost:3000/tests/support/spec_helper.coffee
(if I change the line to "javascripts": ["tests/support/spec_helper.coffee"]
then it works, but obviously that's not what I should be doing)
Looks like a find/replace error where you removed tests
from one place you shouldn't have, maybe? Or didn't finish changing away from tests
to the json-injected location.
Thanks! โจ
I want to be able to control when and if a route responds. My biggest use case is testing loading logic in my app. Currently, if I write the example below, Cypress will auto respond to the image route (with a 404) before my assertion.
it "displays loading gif on image load", ->
cy.route
url: /image/
response: {http://cdn.morguefile.com/imageData/public/files/g/g3c59w/03/l/1427371209n1lyb.jpg}
cy.get("a").click()
cy.get("img").should("have.attr", "src").to("match", /ajax.gif/)
Some suggestions:
autoRespond: false
to be passed into cy.route()
Sometimes I write a test like the following that I expect to pass:
cy
.get("#button").as("submitBtn")
.get("@submitBtn", {visible: true})
.click()
.get("@submitBtn", {visible: false})
Since Cypress is only querying the DOM for my aliased element on the first command, it will always see the submit button as visible (although the state in the DOM has changed after my click as dictated by my application logic).
If I pass options to an alias (visible, exist, length), I want the DOM to be re-queried to find that current el, since I'm likely asserting on it's current state.
A simple unit test with no cypress commands. chai-jQuery is not working.
Example
<div class="foo"></div>
it("has class foo", function() {
return expect($div).to.match("div.foo");
});
jQuery child commands should output a similar error to cy.contains
when their command fails finding their elements.
<input type="text" name="search">
<i class="fa-spinner"></i>
cy.get("input").find(".fa-spinner")
Display Error:
could not find `.fa-spinner` within the element: input
Need to be able to hover in/out of DOM elements.
cy.get("@firstRow").hover()
I'm not sure what a stop hover command would look like.
Currently I would achieve this with mouseOver
and mouseOut
events. The hover command could follow a similar convention.
Other considerations:
If I pass in the option respond: false
to cy.route()
command, the command log is displaying error:
CypressError: cy.route() cannot accept an undefined or null response. It must be set to something,
even an empty string will work.
Cypress should not be validating the response when option respond: false
is defined.
Example code
describe "class doesn't load", ->
cy.route({
url: /^\/classifications\/\d+/
respond: false
}).as("classNotResponded")
A cypress generated id is being inserted after any strings that match a test title. In the example below, you can see that my cy.get()
command has had an id inserted at [name='comment [0eo]']
. This is due to the fact that later I have a test titled "comment".
describe "paragraph questions", ->
it "prefills comment with value [1eq]", ->
cy.get("textarea[name='comment [0eo]']").should("have.value", "Hello world")
describe "comment [0ep]", ->
it "appends resources [0ei]", ->
cy.get("[name='comment']").should("have.value", "Hello world, how are you?")
cy.route(/accounts/, {}).as("accountsGet")
cy.get("input")
.type("Spring").wait("@accountsGet")
.clear().type("Spring2").wait("@accountsGet")
The first .type
causes an XHR (which we explicitly wait for)
Then the 2nd .type
causes a 2nd XHR (which we also explicitly wait for)
The problem is that the 2nd XHR request is not waited on because Cypress waits for the 1st, which has already resolved.
Add command cy.not()
to filter out elements from a set of matched elements. This will provide an opposite command to the already implemented cy.filter()
.
Example:
<ul>
<li>list item 1</li>
<li class="active">list item 2</li>
<li>list item 3</li>
</ul>
cy.get("li").not(".active")
I want to be able to quickly see the version of Cypress that I am on. Perhaps print this in a window when clicking "About" in the Cypress app.
In the documentation it says the function usage of cy.wait() runs the function until it does not throw. Obviously, there is a timer that makes sure the function doesn't wait forever, but is it possible to change this timer value?
Is it also possible to limit the rate at which it polls the given function?
Maybe this is an odd request, but in my case I know that I have to wait for at least 5 seconds for a roulette animation, but it may be as long as 10 seconds. I could have just done cy.wait(10000), but then in some cases I will have to wait at maximum 5 unnecessary seconds.
When using cy.contains("...", {visible: true})
and a visible element containing that text was not found, this error message displays:
CypressError: Timed out retrying. Could not find any content: 'Loading Dock' in any elements
This error would be more accurate if it said "Could not find any content: 'Loading Dock' in any visible elements."
Example Code
cy.contains("Loading Dock", {visible: true})
Example:
http://localhost:5000/#/map?/
Would love support and documentation for automatically running the Cypress tests with Travis.
Currently cy.server
can only be started after you cy.visit
a remote page.
cy
.visit("http://localhost:7000/dashboard")
.server()
.route(...)
This is problematic because many pages make XHR requests onLoad
. Because cy.visit
resolves when the page's load
event fires, by this time it is often too late. XHR requests may have gone out.
Therefore cy.server
should be able to be invoked prior to a page loading (even though one does not exist).
Any routes
attached to the server should also be carried over.
My code:
describe 'Navigating there [00h]', ->
it 'is in the menu [00i]', ->
cy.server().route 'POST', /users.json/, {}
...crashes immediately with:
CypressError: sinon.js was not found in the remote iframe's window. This may happen if you testing a page you did not directly cy.visit(..). This happens when you click a regular link.
...and it makes me very ๐ฟ
I am calling click
on a el in a dropdown that is animating into view. When Cypress initially gets the coordinates for where the el should be, it doesn't find the element I wanted to click. Instead, it finds another element in the background, then goes through the Cypress logic of finding a parent element with position: fixed
, then attempting to scroll (in case the fixed position element is covering the element I want to click).
It's stuck within this loop of finding a parent element with position: fixed
then attempting to scroll. It eventually times out.
Example Code
it "clicks loading dock in dropdown", ->
cy
.contains("Warehouse").click()
.contains(".k-item", "Loading Dock").click()
When I use command cy.type()
for inputs of type date, time, month, and week the value is not updated for the input. The type command needs to do special logic to inject the values (or do special click / selects / types) due to the formatting / dropdown nature of these inputs.
Date Example
<input name="birthday" type="date">
cy.get("input[name='birthday']").type("11151985").should("have.value", "1985-11-15")
This example's assertion will fail and say expected input to have value of '1985-11-15', but got ''
Time Example
<input name="appt" type="time">
cy.get("input[name='appt']").type("1215am").should("have.value", "00:15:00")
This example's assertion will fail and say expected input to have value of '00:15:00', but got ''
Month Example
<input id="month" type="month">
cy.get("#month").type("February 2012").should("have.value", "February 2012")
This example's assertion will fail and say expected '<input#month.form-control>' to have value 'February 2012', but the value was ''
Week Example
<input id="week" type="week">
cy.get("#week").type("20, 2016").should("have.value", "February 2012")
This example's assertion will fail and say expected '<input#week.form-control>' to have value '20, 2016', but the value was ''
When I pass the options exist or length to a DOM traversal, they do not print in the command log when the implicit assertion passes.
Example Code
it"displays options", ->
cy.get(".answers-list tr", exist: true)
cy.get(".answers-list tr", visible: true)
cy.get(".answers-list tr", length: 55)
When I have an assertion that include to.have.property
, the assertion just prints [object Object]
in the commands UI.
Also, the assertion is getting cut off at a strange place to make it look like "short textAmert" matches "short text", but the full message I logged in the console says:
expected { value: short textAmet } to have a property [object Object] of short textAmet,
and got short textAmet`
Example code
expect(request.requestJSON).to.have.property("value", "short textAmet")
Is it possible to add the option to specify coordinates for a click event on certain types of DOM elements, like canvas?
For example
cy.get("canvas").click(50, 200);
would trigger a click event 50px from the left and 200px from the top of the specified canvas element.
When you have a spy / stub and you have an expectation for the spy / stub, it can potentially time out because it locks up the CPU.
Example
it("lists users", function() {
return expect(cy.agents().spy(App, "execute")).to.have.been.calledWith("list:users:chosen");
});
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.