Git Product home page Git Product logo

cypress-commands's People

Contributors

alejo90 avatar brettz9 avatar dependabot[bot] avatar jennifer-shehane avatar kosai106 avatar lakitna avatar lakitnarabobank avatar piwysocki avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

cypress-commands's Issues

Command to retrieve text from an element

What do you want to accomplish?

I want to be able to assert the full text of an element instead of relying on contains.

Why?

Because in some cases having extra text is a problem and using the current methods you can't properly assert the full text.

The following example is, in some cases, not specific enough. I would like it to fail if the text does not match /^foo$/.

cy.get('div').should('contain', 'foo');

.should('equal', 'foo') does not work here as it would assert agains the element instead of the text.

I want a more specific way to test strings.

Describe possible implementations

cy.get('div')
    .text()
    .should('equal', 'foo');

Additional context

This would be really usefull for complex pages where you need to assert data and such.

TypeScript types for cy.then

Type of feature

  • Add a new command
  • Extend a default Cypress command
  • Change a Cypress-commands command
  • Other

What do you want to accomplish?

A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
I am using Cypress with typescript and would love to use the retry feature of your package

Why?

A short description of why you want to accomplish the things mentioned above.
however I am getting errors related to types.

Argument of type '{ retry: boolean; }' is not assignable to parameter of type 'Partial<Timeoutable>'. Object literal may only specify known properties, and 'retry' does not exist in type 'Partial<Timeoutable>'.ts(2345)

Describe possible implementations

A clear and concise description of what you want to happen.
I am not quite sure how, but I think we need to overwrite the default cypress then typings to include this packages options.

Additional context

Add any other context or screenshots about the request here.

Update plugin to be compatible with Cypress 10

Type of feature

  • Add a new command
  • Extend a default Cypress command
  • Change a Cypress-commands command
  • Other

Hello 👋 I'm writing on behalf of the Cypress DX team. We wanted to notify you that some changes may need to be made to this plugin to ensure that it works in Cypress 10.

For more information, here is our official plugin update guide.

Release cypress-commands@2

Issue to track all the little things that have to be done before publishing.

  • Validate / update readme
  • Validate / update command documentation
  • Bump version to 2.0.0

Casting subject

Type of feature

  • Add a new command
  • Extend a default Cypress command
  • Change a Cypress-commands command
  • Other

What do you want to accomplish?

Initial context: cypress-io/cypress#630 (comment)

The ability to cast values to different primitives to allow us to write something like

cy.get(...)
  .text()
  .castSubjectToANumberInThisCommand()
  .should('be.above', 1);

Why?

To simplify reading your tests. This would replace code like

cy.get(...)
  .text()
  .then((val) => Number(val))
  .should('be.above', 1);

This code isn't bad, but it can be a bit scary for some.

Describe possible implementations

A few possibilities at this point:

Command per cast

cy.wrap('007')
  .number()
  .should('equal', 7);

cy.wrap(123)
  .string()
  .should('equal', '123');

cy.wrap('foo')
  .array()
  .should('equal', ['foo']);

These might be better when named .asNumber(), .asString() and .asArray(). Otherwise you would get confusing chains like cy.get(...).text().number().

Wrapper commands that casts

Example for the .text() command: Add a new .number() command that will retrieve the numeric contents of a subject element.

cy.get('.mrBond')
  .number()
  .should('equal', 7);

On a technical level this would essentially contain .text().then((n) => Number(n)).

Generic cast command

cy.wrap('007')
  .cast('number')
  .should('equal', 7);

Cast in existing commands based on upcoming assertions

For the .attribute() command I made a way to gather the upcoming assertions with decent stability. This is very hacky and we probably shouldn't rely on that if we can help it.

cy.get('.mrBond')
  .text()
  .should('equal', 7);

Cast in existing commands based on an option

cy.get('.mrBond')
  .text({ cast: 'number' })
  .should('equal', 7);

Additional context

The conversation starting at this comment cypress-io/cypress#630 (comment)

Grabbing the value of input and textarea elements

Type of feature

  • Add a new command
  • Extend a default Cypress command
  • Change a Cypress-commands command
  • Other

What do you want to accomplish?

I want an easy way to get the text inside input and textarea elements.

Why?

Right now it's a pain to get these values even though they can be important to assert.

Ways you can assert this value right now:

// Will pass on whitespace
cy.get('input')
    .should('not.have.value', '');

// Will not retry properly
cy.get('input')
    .then((elem) => elem.val())
    .should('not.be.empty');

// Currently the best implementation imo
cy.get('input')
    .should((elem) => {
        expect(elem.val()).to.not.be.empty;
    });

Describe possible implementations

I was thinking about extending its() to use jQueries val function when the subject is a jQuery element and the command is called like .its('value').

cy.get('input')
    .its('value')
    .should('be.empty');

Alternatively, the text() command could be used for this.

cy.get('input')
    .text()
    .should('be.empty');

A third option would be to create an attribute() command that uses jQueries attr function. This would enable much more than just retrieving the value of form elements, but is not great semantically.

cy.get('input')
    .attribute('value')
    .should('be.empty');

Additional context

Ran into this on Gitter.

Generate bundle before distribution

Type of feature

  • Add a new command
  • Extend a default Cypress command
  • Change a Cypress-commands command
  • Other

What do you want to accomplish?

Only distribute bundled files (.js and .d.ts).

Why?

To limit the number of files in the users node_modules we should distribute bundled files.

Describe possible implementations

Use Rollup with lessons learned from another project.

Additional context

This will not change any functionality.

Cypress 3.3.x support for `.request()`

Describe the bug

The .request() method has been overhauled in Cypress 3.3.x. Update tests and make sure the requestBaseUrl still works.

To Reproduce

Clone repo, run tests

Expected behavior

Tests pass

Versions and such:

  • Cypress version: 3.3.x
  • Cypress-commands version: 2.0 (unreleased)

then() doesn't pass down the context

Describe the bug

One can't use this.myAlias inside then() callbacks.

To Reproduce

    specify('aliases work', function () {
        cy.wrap(1).as('myAlias');
        cy.wrap(2).then(function(subj) {
            expect(this.myAlias).to.eq(1); // undefined
        });
    });

Expected behavior

The test succeeds.

Versions and such:

  • OS: Arch Linux
  • Cypress version: 3.4.0
  • Cypress browser: Electron 61
  • Cypress-commands version: 0.2.0

Additional context

A way to fix this would be:

--- node_modules/cypress-commands/lib/then.js.orig	2019-09-07 10:32:52.749110507 +0300
+++ node_modules/cypress-commands/lib/then.js	2019-09-07 10:33:18.125849439 +0300
@@ -23,7 +23,8 @@
  * @yields {any}
  * @since 0.0.0
  */
-Cypress.Commands.overwrite('then', (originalCommand, subject, fn, options = {}) => {
+Cypress.Commands.overwrite('then', function(originalCommand, subject, fn, options = {}) {
+    const ctx = this;
     if (_.isFunction(options)) {
         // Flip the values of `fn` and `options`
         [fn, options] = [options, fn];
@@ -86,7 +87,7 @@
      */
     async function executeFn() {
         // Execute using the original `then` to not reinvent the wheel
-        return await originalCommand(subject, options, fn)
+        return await originalCommand.call(ctx, subject, options, fn)
             .then((value) => {
                 if (options.log) {
                     consoleProps.Yielded = value;

But for one reason or another originalCommand doesn't pass down the context either.

Cypress 12 Compatibility

Greetings from the @cypress-io team. Cypress 12 is coming out next week, and some changes might affect your plugin. One of the big changes is introducing a new API to register custom commands, which helps fix one of the oldest and most annoying issues with Cypress, the “Detached DOM” error.

For commands that are classified as queries (mainly used to return something like a DOM element), there is a new Cypress.Commands.addQuery method. The addQuery method greatly simplifies writing custom query commands and has the benefit of not encountering detached DOM errors.

If your plugin currently registers custom command “queries”, we recommend updating your plugin to use the new API for Cypress 12. Note the API is only going to be in Cypress 12 and newer.

To test out a prerelease version of Cypress 12, you can follow the instructions for installing a prerelease binary here, but instead of using the develop branch use the release/12.0.0 branch.

We recommend all plugin authors test their plugins against the Cypress 12 prerelease to check for compatibility.

If you have any questions, contact us by pinging me on this issue or in our Discord server.

You might find our Retry-ability Guide (updated to cover the latest changes), and Cypress 12 Migration Guide | Cypress Documentation helpful as well.

Thanks

How to use this

How do I actually use these commands in my test files? I don't understand, the documentation tells me some random steps but actually invoking say .text() function doesn't work.

text() command adds spaces if element's content has <wbr> tags inside

Describe the bug

text() commands adds spaces if element's content has <wbr> tags inside

To Reproduce

HTML to reproduce:
<a href="/cell_phones/mobile_phone_samsung_a207f_galaxy_a20s_32_duos_red_sm-a207fzrdsek.html" class="product-name">Мобильны<wbr>й телефон Samsung A207F Galaxy A20s/32 Duos Red (SM-A207FZRD<wbr>SEK)</a>

cy.get('.product-name').text()
yields
Мобильны й телефон Samsung A207F Galaxy A20s/32 Duos Red (SM-A207FZRD SEK)

Expected behavior

cy.get('.product-name').text()
yields
Мобильный телефон Samsung A207F Galaxy A20s/32 Duos Red (SM-A207FZRDSEK)

Versions and such:

  • OS: Windows 8.1
  • Cypress version: 4.12.1
  • Cypress browser: Chrome
  • Cypress-commands version: 1.1.0

Additional context

The native approach cy.get('.product-name').invoke('text') gives the expected result of Мобильный телефон Samsung A307F Galaxy A30s/32 Duos White (SM-A307FZWUSEK)

Issues with Cypress 6.4 with fixes

Describe the bug

I pulled down the code base and updated Cypress from 5.x to 6.x. I found two failing tests, one relatively simple issue and one I believe may be a test which has been removed from the Cypress suite.

To Reproduce

Delete node_modules and package-lock.json
Change Cypress version in package.json to ^6.0.0

Reinstall

Expected behavior

All tests run green

Screenshots

Versions and such:

  • OS: Ubuntu 20.04
  • Cypress version: 6.4
  • Cypress browser:
  • Cypress-commands version:

Additional context

There are two failing tests.

Failure in then

then.js

Line 320

    expect(err.message).to.equal('Timed out retrying: expected 5 to equal 4');

Fails because the message from Cypress has changed to include the number of millseconds. Changing to

    expect(err.message).to.contain('expected 5 to equal 4');

Causes the test to pass and verifies the intended result.

Cypress runner failing on copied/request.js

here is a folder under cypress integration, copied. It contains one spec, request.js. This variant fails the test
is deprecated but does not fail even on 500 when failOnStatus=false

The full error is:

cy.request() failed on:

http://localhost:1234/foo

The response we received from your web server was:

  > 500: undefined

This was considered a failure because the status code was not 2xx or 3xx.

If you do not want status codes to cause failures pass the option: failOnStatusCode: false

Separate base url for `.request()`

Type of feature

  • Add a new command
  • Extend a default Cypress command
  • Change a Cypress-commands command
  • Other

What do you want to accomplish?

Inspired by @thekiiingbob on the Cypress Gitter.

// Visit http://www.domain.com/foo
cy.visit('/foo'); 

// Request from http://api.domain.com/foo
cy.request('/foo');

Why?

@thekiiingbob has an app where he needs to .visit() to http://www.domain.com and .request() to http://api.domain.com. To keep things clean and concise it would be great if there are separate base urls for .visit() and .request().

Describe possible implementations

Overwrite the .request() command to look at the config key requestBaseUrl. If this key is undefined use the normal baseUrl instead.

Return all elements found by contains

What do you want to accomplish?

I want to be able to select multiple elements by its contents.

Why?

The command .contains() only returns a single element. In most cases this is great, but some specific cases you want to find multiple elements by its contents.

In most of these cases, you can make a workaround using .filter(), but this requires you to write custom, often untestable code. Adding this to a command makes sure you don't have deal as much with test code bugs.

Describe possible implementations

Add an option to the .contains() command to allow you to do this. The option could be named multiple like in the default .click().

cy.get('div')
    .contains('foo', { multiple: true });

Additional context

By default .contains() always selects the deepest element it can find, if there are multiple it will grab the first of those. This behaviour should only change if the multiple option is set.

text command does not preserve order of inline element

Describe the bug

Given the following situation:

<p>Lorum <b>ipsum</b> dolor sit amet.</p>
cy.get('p').text({ depth: Infinity })

Will yield:

"Lorum dolor sit amet. ipsum"

That is an unexpected order.

Expected behavior

It yields

"Lorum ipsum dolor sit amet."

Solution

The following change to the text() command seems to solve the issue.

/**
 * @param {JQuery} element
 * @param {number} depth
 * @return {string}
 */
function getTextOfElement(element, depth) {
    return element
        .contents()
        .filter((_, content) => {
            console.log(content)
            // Only keep the text nodes
            return content.nodeType === Node.TEXT_NODE
                || (content.nodeType === Node.ELEMENT_NODE && depth > 0);
        })
        .map((_, content) => {
            if (content.nodeType === Node.TEXT_NODE) {
                // Get the text from the text node
                return content.data.trim();
            }
            if (content.nodeType === Node.ELEMENT_NODE) {
                // Get the text from child element
                return getTextOfElement($(content), --depth)
            }
        })
        .toArray()
        .join(' ')
        .trim();

Attribute command

Type of feature

  • Add a new command
  • Extend a default Cypress command
  • Change a Cypress-commands command
  • Other

What do you want to accomplish?

I want a neat way to access an element's attributes so I can assert them.

Why?

The current way of doing so would be something like below. This is unnecessarily verbose and can be confusing.

// Using then
cy.get('div')
  .then((elem) => elem.attr('foo'))
  .should('equal', 'bar');
// Without then (and thus with retry)
cy.get('div')
  .should((elem) => {
    const attribute = elem.attr('foo');
    expect(attribute).to.equal('bar');
  });

Describe possible implementations

A command that basically wraps the jQuery attr() function

cy.get('div')
  .attribute('foo')
  .should('equal', 'bar');

Additional context

It should throw an error if the attribute does not exist on the subject (unless the upcoming assertion demands it not existing).

It should yield a string when applied to a single element. It should yield an array of strings when applied to multiple elements.

Make a command not count towards the reliability limit

Type of feature

  • Add a new command
  • Extend a default Cypress command
  • Change a Cypress-commands command
  • Other

What do you want to accomplish?

When an assertion fails the previous command will be retried until the assertion passes. Only one command will be retried. I want to find a way to make Cypress retry 2 or more commands instead.

Why?

This can be very useful for improving tests stability when building custom commands or when added to certain commands like for example text().

Describe possible implementations

The only existing thing in Cypress that resembles this behaviour is the should(fn). Creating an alias for should is a last resort to get this behaviour. It would be a lot better if we can hook into the underlying logic of should instead to bypass the default chaining logic.

Additional context

The first step would be to find out if this is even possible. Next step would be to find out if this behaviour can be added to existing commands with an option.

cy.get(element).text() seems to be not working

Changes should be made to

  • General documentation (ex. README.md)
  • Command documentation (ex. docs/then.md)
  • Command type definitions / Intellisense

Describe the improvement

I can't get text() command working - it doesn't return text as a string.

Why?

Why do you think there should be a change?

Possible improvements

How can we improve it? You probably don't need to answer this question if you are writing the improvements yourself.

Additional context

Add `timeout` option to `then`

The default then command accepts a timeout option. Can you extend your types to mirror (or import) the cypress types? In 4.1.0, this is the Timeoutable interface.

BTW I love this plugin. Thank you for writing it!

Attribute Command not working

Describe the bug

When you try to use the .attribute command, you get:
queue.filter is not a function

It looks like Cypress removed the .filter method in version 8.3. I played with this locally and it seems to work if I just switch it to use .find

However, I think I'm missing something with the invoked

To Reproduce

Write any test that uses the .attribute command

Expected behavior

The .attribute command should not throw an error.

Versions and such:

  • OS: Windows 10
  • Cypress version: > 8.2
  • Cypress browser: Any
  • Cypress-commands version: 1.1.0

Additional context

The problem line is here:

.filter({ name: commandName })

I cannot seem to find any info on the .filter method on Cypress docs or in the issues list.

I've seen the problem in Cypress 8.3 and 8.3.1

I can try to do a PR to fix it if that would help.

Thanks!

Ricardo Diaz

Cannot get value in .text() from input

Describe the bug

I'm trying to obtain a value/text within the via .text(), it always brings back an empty string - but looking at the logs it contains a jQuery and within it, it contains value="MY_VALUE".
I did via <div with .text() and it worked, I just have an issue with <input - is there away to obtain this from the results within the jQuery. I did the following things but didnt work.
I'm not sure if this is a bug or due to my lack of understanding please help :)

Code

const getToken = cy.get('#copiedToken').text() - empty string

const getToken = cy.get('#copiedToken').text() let bla = getToken[0].value - this always gives undefined value - but in jQuery it shows my text in the value part

cy.get('#copiedToken').text({ depth: Infinity }).then(($info) => { cy.log($info) }) - this gives empty string

Screenshots

Screenshot 2020-08-12 at 15 01 36

Screenshot 2020-08-12 at 15 01 47

Versions and such:

  • OS: Mac
  • "cypress": "^3.8.3",
  • "cypress-commands": "^1.1.0",

Additional context

Add any other context about the problem here.

Can't requestBaseUrl be undefined?

Describe the bug

cy.request() fails with:

TypeError: Cannot read property 'length' of undefined

when no requestBaseUrl present in cypress.json.

To Reproduce

cypress/integration/1.spec.js:

describe('cy.request', function() {
    it('succeeds', () => {
        cy.request('GET', '/some/relative/url');
    });
});

Expected behavior

It succeeds.

Versions and such:

  • OS: Arch Linux
  • Cypress version: 3.4.0
  • Cypress browser: Electron 61
  • Cypress-commands version: 0.2.0

Additional context

The culprit line is this one.

Travis pipeline

A basic Travis pipeline to ensure all tests pass and there are no linting errors.

Cypress-commands 1.0.0

I've been thinking that we should probably solidify the package in major version 1.

Therefore I would like to invite everyone to suggest any changes that should be made before we do this.

I'll leave this open for about a month after which I'll publish 1.0.0, even if there are no changes. This issue will serve as a tracker for 1.0.0.

TODO

  • Version bump to 1.0.0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.