abhinaba-ghosh / cypress-react-selector Goto Github PK
View Code? Open in Web Editor NEW:zap: cypress plugin to locate react elements by component, props and state
Home Page: https://www.cypress.io/
License: MIT License
:zap: cypress plugin to locate react elements by component, props and state
Home Page: https://www.cypress.io/
License: MIT License
[email protected]
[email protected]
[email protected]
node: v14.15.1
Create simple nextjs app by yarn create next-app --example with-typescript .
create a test case.
Could not find instance of React in given element
will be thrown at random intervals
describe('App tests', () => {
before('Visits the homepage', () => {
cy.visit('/');
cy.viewport(800, 600);
cy.waitForReact();
});
it('Locate Bob', () => {
cy.react('Link').should('contain', 'Users List');
cy.react('Link').contains('Users List').click();
cy.react('Link').should('contain', '102: Bob');
cy.react('Link').contains('102: Bob').click();
cy.react('ListDetail').should('contain', 'Detail for Bob');
cy.getReact('ListDetail')
.getProps('item')
.should('eql', { id: 102, name: 'Bob' });
});
});
Iam just trying this library i followed the steps in the setup guide but it still got this error :
cy.waitForReact is not a function
Note: I am using it with typescript
tsconfig:
{
"extends": "../tsconfig.json",
"include": ["../node_modules/cypress","../node_modules/cypress-react-selector", "*/*.ts"],
"compilerOptions": {
"types": ["node", "cypress", "cypress-react-selector"]
}
}
cypress.json :
{
"baseUrl": "http://localhost:3000",
"integrationFolder": "./src/tests/e2e/integration",
"screenshotsFolder": "./src/tests/e2e/screenshots",
"supportFile": false,
"pluginsFile": false,
"video": false,
"env": {
"cypress-react-selector": {
"root": "#root"
}
}
}
version :
"cypress-react-selector": "^2.2.2",
"cypress": "^6.2.1",
I'm getting the [cypress-react-selector] not loaded yet
when the cypress console is telling me it has been loaded.
I moved it to a before
call as well, just in case that was the issue, but it behaves the same.
cypress.json:
{
"pluginsFile": false,
"baseUrl": "http://localhost:8080",
"env": {
"cypress-react-selector": {
"root": "#root"
}
}
}
The test:
beforeEach(() => {
cy.login();
cy.waitForReact();
});
describe("On the Account Management", () => {
context("Page", () => {
it("the form exists", () => {
cy.visit("http://localhost:8080/app/my-account")
cy.react("MyAccountPage").should("be", "visible")
})
})
});
Stack trace:
cypress_runner.js:199777 Error: [cypress-react-selector] not loaded yet. did you forget to run cy.waitForReact()?
at getNodes (http://localhost:8080/__cypress/tests?p=cypress/support/index.js:321:17)
at resolveValue (http://localhost:8080/__cypress/tests?p=cypress/support/index.js:368:16)
at Context.eval (http://localhost:8080/__cypress/tests?p=cypress/support/index.js:394:14)
From previous event:
at getRet (http://localhost:8080/__cypress/runner/cypress_runner.js:155115:20)
From previous event:
at Context.thenFn (http://localhost:8080/__cypress/runner/cypress_runner.js:155133:23)
at Context.then (http://localhost:8080/__cypress/runner/cypress_runner.js:155572:21)
at Context.<anonymous> (http://localhost:8080/__cypress/runner/cypress_runner.js:169999:21)
at http://localhost:8080/__cypress/runner/cypress_runner.js:169423:15
From previous event:
at runCommand (http://localhost:8080/__cypress/runner/cypress_runner.js:169402:8)
at next (http://localhost:8080/__cypress/runner/cypress_runner.js:169548:14)
at http://localhost:8080/__cypress/runner/cypress_runner.js:169576:16
From previous event:
at next (http://localhost:8080/__cypress/runner/cypress_runner.js:169548:34)
From previous event:
at Promise.catch.err.name (http://localhost:8080/__cypress/runner/cypress_runner.js:169589:37)
From previous event:
at run (http://localhost:8080/__cypress/runner/cypress_runner.js:169582:21)
at $Cy.cy.<computed> [as visit] (http://localhost:8080/__cypress/runner/cypress_runner.js:170039:11)
at Context.runnable.fn (http://localhost:8080/__cypress/runner/cypress_runner.js:170263:21)
at callFn (http://localhost:8080/__cypress/runner/cypress_runner.js:104396:21)
at Test.../driver/node_modules/mocha/lib/runnable.js.Runnable.run (http://localhost:8080/__cypress/runner/cypress_runner.js:104383:7)
at http://localhost:8080/__cypress/runner/cypress_runner.js:175798:28
From previous event:
at Object.onRunnableRun (http://localhost:8080/__cypress/runner/cypress_runner.js:175786:17)
at $Cypress.action (http://localhost:8080/__cypress/runner/cypress_runner.js:166429:28)
at Test.Runnable.run (http://localhost:8080/__cypress/runner/cypress_runner.js:174172:13)
at Runner.../driver/node_modules/mocha/lib/runner.js.Runner.runTest (http://localhost:8080/__cypress/runner/cypress_runner.js:105055:10)
at http://localhost:8080/__cypress/runner/cypress_runner.js:105181:12
at next (http://localhost:8080/__cypress/runner/cypress_runner.js:104964:14)
at http://localhost:8080/__cypress/runner/cypress_runner.js:104974:7
at next (http://localhost:8080/__cypress/runner/cypress_runner.js:104876:14)
at http://localhost:8080/__cypress/runner/cypress_runner.js:104942:5
at timeslice (http://localhost:8080/__cypress/runner/cypress_runner.js:98868:27)
I have a date picker component that has no text input, only various buttons, so it would be difficult to set the date in tests by simulating clicks. So I would like to get the function stored in its onDateChange property to call it directly. However I cannot access the property.
With this
cy.react('DateInput').eq(0).getProps('onDateChange').then(onDateChange => onDateChange(new Date(2021, 4, 4)))
I get the error Previous subject found null. getProps() is a child command. Use with cy.getReact()
While with this
cy.getReact('DateInput').eq(0).getProps('onDateChange').then(onDateChange => onDateChange(new Date(2021, 4, 4)))
I get the error
cy.eq() failed because it requires a DOM element.
The subject received was:
> [Object{5}, Object{5}]
The previous command that ran was:
> cy.then()
All 2 subject validations failed on this subject.
See details in cypress-io/cypress-react-unit-test#381
I don't know where to ask this question, I think this is the only communication channel.
I want to get the state of the component, without knowing the value, all the examples I have seen is with the value of the state and filtering on the based on that.
Just like getProps
cy.getReact('reactComp') .getProps('myProp') .then((data) => { result = data })
I need the same for state
cy.getReact('reactComp') .getCurrentState() .then((data) => { result = data.stateItem }) // returns {t: function(){}}
I have added data-cy=id
property with relevant Id to the react component (as recommended in the cypress doc and is very convenient).
I am trying to get react component by this property:
cy.getReact('ComponentName', {props: {data-cy: id}})
and getting a syntax error on compilation: Unexpected token, expected ","
To have the ability to get react components using data-cy
property.
The first thought that comes to my mind - transmit properties and their values as a string, like other input parameters in cypress.
So, the previous command will look like:
cy.getReact('ComponentName', '{props: {data-cy: id}}')
I just learned of this library and after installing 2.2.1 and adding to an existing test I hit a type error on require.resolve
in the call cy.waitForReact(..)
.
No issue after downgrading to 2.2.0.
Hi,
We're using cypress-react-selector
with a Next.js 10 project. While our tests ran fine with Next.js 9.5.3, after upgrading Next.js to 10, something is causing cypress-react-selector
to stop finding React components at some seemlingly random point.
Some example code:
/// <reference path="./../../support/index.d.ts" />
describe('Click through on boarding flow', () => {
before(() => {
cy.visit(`${Cypress.config().baseUrl}`)
})
it('should walk through all of the screens in the on boarding flow', () => {
cy.fixture('users').then(users => {
cy.login(users.test.email)
.react('Panel')
.should('contain', users.test.email)
.visit(
`${Cypress.config().baseUrl}/enter-code?code=${Cypress.env(
'E2E_TEST_MFA_CODE',
)}`,
)
.waitForReact()
cy.react('Panel').should('exist')
cy.react('Link').last().click()
cy.react('Step').react('Button').last().click()
// ... (truncated)
})
})
cypress-react-selector
for some reason fails to see the Step
component, where under Next.js 9.5.3 it would see it just fine. The problem does not seem to be specific to the Step
component, for in another branch with a slightly different test sequence, it fails on a different component.
I'd be happy to paste any logs that might help diagnose the problem. For starters here's Cypress' output:
14 assert expected <div.css-1jqjf6a> to exist in the DOM
15 log Finding <Link>
16 last
17 click
(new url)
http://localhost:5000/signup/some-feasture/some-page
18 task readResqFile
19 log [cypress-react-selector] loaded
20 log Finding <Step>
21 then function(){}
Error
Component not found <Step>
There can be multiple reasons for it.
> Check the root is defined as a env parameter (cypress.json config file).
> If the root is defined correctly, check other parameters - component name, props and state objects
Or, raise an issue with proper code samples here: https://github.com/abhinaba-ghosh/cypress-react-selector/issues
node_modules/cypress-react-selector/src/reactHandler.js:202:1
200 | if (!value) {
201 | if (retries < 1) {
> 202 | throw new Error(
| ^
203 | getComponentNotFoundMessage(
204 | component,
205 | reactOpts.props,
at eval (webpack:node_modules/cypress-react-selector/src/reactHandler.js:202:1)
From previous event:
at getRet (http://localhost:5000/__cypress/runner/cypress_runner.js:155117:21)
From previous event:
at Context.thenFn (http://localhost:5000/__cypress/runner/cypress_runner.js:155135:24)
at Context.then (http://localhost:5000/__cypress/runner/cypress_runner.js:155574:22)
at Context.<anonymous> (http://localhost:5000/__cypress/runner/cypress_runner.js:170040:22)
at <unknown> (http://localhost:5000/__cypress/runner/cypress_runner.js:169464:16)
From previous event:
at runCommand (http://localhost:5000/__cypress/runner/cypress_runner.js:169443:9)
at next (http://localhost:5000/__cypress/runner/cypress_runner.js:169589:15)
at <unknown> (http://localhost:5000/__cypress/runner/cypress_runner.js:169617:17)
Relevant package versions:
Our test suite:
"cypress": "^5.6.0",
"cypress-react-selector": "^2.2.1",
"resq": "^1.10.0",
Our app:
"next": "^10.0.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
cypress.json:
{
"baseUrl": "http://localhost:5000",
"fixturesFolder": "./cypress/fixtures",
"integrationFolder": "./cypress/integration/tests",
"projectId": "xxx"
}
Hello,
Recently we have updated our cypress-related packages:
"@testing-library/cypress": "^6.0.0" => "@testing-library/cypress": "^7.0.3"
"cypress": "^5.4.0" => "cypress": "6.2.1"
"cypress-react-selector": "^2.2.0" => "cypress-react-selector": "2.2.2"
After those changes we are having problem with cy.waitForReact();
In our test we are calling this method inside it()
.
We are getting error:
cy.readFile() must be passed a non-empty string as its 1st argument. You passed: 396.
Before the update everything worked correctly.
cypress.json
{
"baseUrl": "http://localhost:3000",
"cypress-react-selector": {
"root": "selector"
}
}
tsconfig.json
{
"extends": "../tsconfig.json",
"compilerOptions": {
"isolatedModules": false,
"target": "es5",
"lib": ["es5", "dom"],
"types": [
"node",
"cypress",
"@types/testing-library__cypress",
"cypress-react-selector"
]
},
"include": ["../node_modules/cypress", "**/*.ts"]
}
The test:
it('Go to magazine page', () => {
cy.visit('/magazine/test-user-magazine');
cy.get('h1').should('contain', 'test user magazine');
cy.get('h2').should('contain', 'test user magazine');
cy.get('p').should('contain', 'test user magazine description');
//log in and go to edit page
cy.login();
cy.get('a[id="fab"]').click();
cy.url().should('contain', '/magazine/test-user-magazine/edit');
cy.waitForReact();
//change magazine article switch to approved
cy.get('input[id=defaultAutoAccept]').click({ force: true });
cy.getReact('MagazineEditComponent')
.getCurrentState()
.should('have.property', 'magazine')
.should('have.property', 'articlesApprovedByDefault')
.and('eq', true);
});
cy.login()
does log in by request and its command writen by us.
Is there some issues with versioning here? Maybe there was breaking change in cypress update?
It'd be nice to be able to chain calls to .react()
, so we can query child components the exist under found parent components.
Consider this scenario:
const ErrorMessage: React.FC<{ hasError }> = ({ hasError }) => {
if (hasError) {
return <p>An error occurred</p>;
} else {
return null;
}
};
const FormField: React.FC<{ name: string }> = ({ name }) => {
return (
<div>
<input name={props.name} />
<ErrorMessage hasError={false}/>
</div>
);
};
function MyForm() {
return (
<form>
<FormField name="username" />
<FormField name="password" />
</form>
);
}
I'd like to query the error message for the username
field.
If I have two forms on the page that have a username
FormField, I would need to add some other way to distinguish them in my markup. I end up having to start with a react()
call, then chaining it with JQuery selectors, which isn't foolproof and requires additional changes to the markup (e.g. adding role
to the error message's p
element).
I'd like to do something like this:
cy.react('MyForm').react('FormField', { name: 'username' }).react('ErrorMessage').should('not.be.visible');
Hi,
I don't know if the Cypress options are fully respected.
cy.react( "MyComponent", { props: { name: "testComponent" } }, { timeout: 20000 } ).should("exist");
The timeout I pass there isn't respected ( that component takes a little while to load due to api calls, 20sec is extreme I know ), but still the cy.react uses the default timeout + 100 sec to check if the component is present.
Could this be looked at?
Fluent chained queries doesn't work properly with multiple items.
macOS 10.15.7
Chrome 86.0
[email protected]
cypress-react-selector@ > 2.0.3 (checked on 2.0.4, 2.1.0, 2.2.0).
'button', { props: { type: 'submit' } }
. cy.react('modal', { hooks: { Context: { modalParams: { type: 'fileCreateModal' } } } })
.react('button', { props: { type: 'submit' } })
.click();
Cypress error:
cy.click() can only be called on a single element. Your subject contained 2 elements. Pass { multiple: true } if you want to serially click each element.
The same code works just fine in [email protected].
The element is clicked, because we filtered out the extra elements by finding the parent element.
See details in cypress-io/cypress-react-unit-test#379
Built-in Cypress retry-ability https://on.cypress.io/retry-ability
Example of retrying assertions in this file https://github.com/cypress-io/cypress-xpath/blob/master/src/index.js#L116
This error occurs many times while running the test, sometimes I just close and re-run the Cypress, it works without any change in code. Sometimes just simple refresh works.
This is painful to restart or re-run, again and again, more-over the test will run in the CI pipeline, which will fail the whole pipeline together.
Following the console error message:
There is nothing special in the code:
....
before(() => {
cy.waitForReact()
....
})
it('do something expected', () => {
cy.getReact('amazingReactComponent')
.getProps('amazingProp')
.then((data) => {
result = data
})
})
....
fluent commands are retrying only if there is an assertion with single commands. But, consecutive react()
or getReact()
not retrying themselves . Suppose:
cy.react('ABC').should('have.length', 1); // retrying
cy.react('XYZ').react('ABC').should('have.length', 1); //not-retrying the first react call if node not found
Sorry if I am not using your plugin correctly, I was iterating over all clickable images and checking whether they spawn a modal like they are supposed to.
When using cy.wrap
cy.react
is no longer able to find anything, but when I use image.trigger("click")
instead of cy.wrap
cy.react
works again, but the click doesn't get triggered on the second iteration of the loop.
It seems like .each
and .wrap
have a funky interaction with .react
cy.react('FeatureImg').each(image => {
// if this line exists, the cy.reacts below can't find anything anymore
cy.wrap(image).scrollIntoView().click();
// replacing the line above the code below allows the cy.react below to work,
// but this line is not executed on any subsequent iterations of the loop ?
// image.trigger("click");
cy.react('ModalWrapper').should('exist');
cy.react('ModalButton').should('exist').trigger('click');
});
Whenever I try to run my Cypress tests on version 2.3.1
, I get the webpack compilation error described below. This has already been mentioned in another issue, but I thought it best to create a separate issue for this exact bug.
yarn run v1.22.4
$ C:\Users\toblo\Code\vms\node_modules\.bin\cypress run --headless --quiet --record false
Couldn't find tsconfig.json. tsconfig-paths will be skipped
Oops...we found an error preparing this test file:
cypress\support\index.js
The error was:
Error: Webpack Compilation Error
./node_modules/cypress-react-selector/src/reactHandler.js 124:62
Module parse failed: Unexpected token (124:62)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| value = Cypress.$(value);
| }
> return cy.verifyUpcomingAssertions(value, reactOpts?.options, {
| onRetry: resolveValue,
| });
@ ./node_modules/cypress-react-selector/index.js 8:4-33
@ ./cypress/support/index.js
This occurred while Cypress was compiling and bundling your test code. This is usually caused by:
- A missing file or dependency
- A syntax error in the file or one of its dependencies
Fix the error in your code and re-run your tests.
This seems to be caused by the question mark, which is invalid JS syntax. Perhaps some TypeScript isn't being compiled on release or something? The same happens on line 238, as well as twice on line 73 of utils.js
. I did a test where I replaced the question mark with something like this (reactOpts || {}).options
and everything seemed to work.
Downgrading to 2.2.2
also fixed the issue.
My tests are working fine on local, but while running on CI the tests fails as soon as they encountered cy.react
command. Not sure, how and what to debug in this case.
[email protected]
cypress-react-selector@ = 2.2.0
CI: Azure
AssertionError: Timed out retrying: Expected to find element:
undefined, but never found it. at Context../node_modules/cypress-react-selector/src/reactHandler.js.exports.react (http://localhost:3000/__cypress/tests?p=cypress/support/index.ts:18089:6)
cy.getReact('ModalButton').nthNode(0).should('exist').trigger('click');
Produces this result, if getReact cannot find a component
it('Shows Modals for Buttons', () => {
cy.visit('/');
cy.waitForReact(1001);
cy.getReact('MediumButtons')
.should('exist')
.each(node => {
cy.wrap(node)
.getProps('buttons')
.then(buttonsProp => {
for (
let buttonIndex = 0;
buttonIndex < buttonsProp.length;
buttonIndex += 1
) {
const { btnName, modal, btnUrl }: Button = buttonsProp[buttonIndex];
if (!modal) continue;
cy.react('BtnListWrap', { props: { href: btnUrl } })
.should('exist')
.eq(0)
.click()
.then(() => {
//cy.react('ModalWrapper').should('exist');
cy.getReact('ModalButton').nthNode(0).should('exist').trigger('click');
});
}
});
});
});
getProp(propName)
and getCurrentState()
apicy.react().react().....
Hi Abhinaba,
I'm trying to read the value of a prop from a component using:
cy.getReact('HomeWelcome').getCurrentState()
When I run it I get the following error in Cypress:
Error: Component not found **<HomeWelcome>**
There can be multiple reasons for it.
> Check the root is defined as a env parameter (cypress.json config file).
> If the root is defined correctly, check other parameters - component name, props and state objects
My cypress.json
looks like so:
{
"chromeWebSecurity": false,
"env": {
"cypress-react-selector": {
"root": "#root"
}
}
}
And after reading some other issues and your readme, I tried to add cy.waitForReact()
to the before()
but then I get the following error:
TypeError: require.resolve is not a function
Because this error occurred during a 'before all' hook we are skipping the remaining tests in the current suite: 'Home'
Some other things to note:
HomeWelcome
is a nested componentBrowserRouter
with Async react-code-splitting
Any ideas?
Hi there,
This is not an issue but was wondering if there was a way to change the prop values after selecting the component?
Hello, your plugin looks very suitable for me, but I have trouble with its setup.
Basic cypress project without any app:
.
| cypress.json
| package.json
| package-lock.json
--cypress
| --integration
| | --spec.js
| --plugins
| | --index.js
| --support
| | --index.js
--node_modules
npm install --save resq
npm i --save cypress-react-selector
import 'cypress-react-selector';
npx cypress open
C:\..\.\node_modules\cypress-react-selector\index.js:1
import { waitForReact } from './src/resqInjector';
^
ParseError: 'import' and 'export' may appear only with 'sourceType: module'
npm install typescript
{
"compilerOptions": {
"sourceType": "module",
"types": ["node", "cypress", "cypress-react-selector"]
}
}
So, can you please tell me what I am doing wrong, what modules should be preinstalled. I have already searched about this issue and I guess it relates to the preprocessor need.
Taking into account the installation guide may be updated.
I get the following error:
[cypress-react-selector] not loaded yet. did you forget to run cy.waitForReact()?
It looks like window.resq is undefined.
home.spec.js:
describe('The Home Page', () => {
before(() => {
cy.visit('/');
cy.waitForReact();
});
it('shows the header', () => {
cy.react('Header')
.should('be', 'visible');
// .should('have.length', 1);
});
});
cypress.json:
{
"baseUrl": "http://localhost:3000",
"env": {
"cypress-react-selector": {
"root": "#root"
}
}
}
support/index.js:
import './commands';
import 'cypress-react-selector';
I'm using the cy.react function to find a row in a list and select it. if I run it 10 times on the same list and same data, maybe half the time it will find the row and select it, the other half of the time it fails with "cy.click() failed because it requires a DOM element" which I assume means it hasn't found it. Have tried adding cy.wait() before with different durations but even adding multiple seconds to the wait to make sure it's loaded still have the same issue. Below is an example of the code I'm using.
I've verified that the name is unique.
cy.react('Link');
cy.react('Link', {props: {name: 'mdRow0'}}).click();
cypress.json
{ "chromeWebSecurity": false, "viewportWidth": 1500, "viewportHeight": 1000, "env": { "cypress-react-selector": { "root": "#root" } } }
When I try to select component by react
command:
cy.react('MyComponent')
This happened when MyComponent is wrapped with React.Fragment:
class MyComponent extends React.Component {
render (){
return (
<React.Fragment>
<div>tested component</div>
<div>tested component</div>
</React.Fragment>
)
}
}
Without React.Fragment is ok. Also there is no problem using cy.getReact('MyComponent')
version:
"cypress": "6.0.0",
"cypress-react-selector": "2.2.1",
Not sure if I'm doing something wrong OR it's the accepted behaviour.
Browser: any
[email protected]
cypress-react-selector@ = 2.2.0
I'm using mix of .react and .get/.find of cypress while finding any element. There are certain situation when I want to limit the scope of .react() to certain div children. But using .react gives me all the elements on the page instead of the matching one from the scope.
Pseudo example:
cy.get('parent-locator') .react('MyReactComponent') .click();
Error:
More than one element found for click
Steps to Reproduce:
Expected Results
Component found each time
Actual Results
Component is reliably found on the first test, always fails on the second and fails on the 3rd about 2/3rds of the time
I've added an example at https://github.com/DaveHarlow/cypress-react-selector-issue
I have a number of IconButton
components on a page. They are mostly differentiated by where they are on the page, so different parents. can I drill down from a selected parent to child?
At line 22 of https://github.com/abhinaba-ghosh/cypress-react-selector/blob/master/index.js, the error message states:
React Selector not loaded yet. did you forget to run cy.waitToLoadReact()?
but I believe that as a user of this plugin we are expected to run cy.waitForReact()
? It looks like waitToLoadReact()
is something being called "under the covers", not what a user of the plugin is expected to do?
This is a rough sketch of a dummy component structure that should demonstrate the issue:
const ErrorMessage: React.FC<{ hasError }> = ({ hasError }) => {
if (hasError) {
return <p>An error occurred</p>;
} else {
return null;
}
};
function MyForm() {
return (
<form>
<div>
<input/>
<ErrorMessage hasError={false}/>
</div>
<div>
<input/>
<ErrorMessage hasError={false}/>
</div>
</form>
);
}
In my Cypress test, I query the error messages like so:
cy.react('MyComponent').should('not.be.visible');
However, Cypress fails with the error message TypeError: Cannot read property 'nodeType' of undefined
.
The console log shows Applied to: [undefined, undefined]
.
I can see the ErrorMessage
components in the React Dev Tools, but they have no corresponding node in the DOM.
So, looks like cypress-react-selector
is finding the component nodes, but pushing undefined
to the result array.
Should this selector filter out any "undefined" entries from the returned array?
There's an easy workaround (in the title) but cypress-react-selector fails when using PnP due to attempting cy.readfile() on resq, due to PnP storing everything as an archive instead of unpacking.
Can be got round via:
yarn add resq -D
yarn unplug resq
But might be worth adding to the readme?
I am using redux-form
that has a <Field>
component. It actually doesn't render the input, instead it offers a component
property where another component is used to render the input. This is a common pattern in React, as it is also seen in Formik's Field element and other places.
The issue is that the <Field>
has a name
property, and the rendered component gets a set of properties passed to it that include that name. In other words, the name
is nested in another property:
<Field name="workEmail" component={MyEmailInput} ... />
and <MyEmailInput>
gets the props:
input: { name: "workEmail", onBlur = f(), onChange = f(), ... },
meta: { active: false, autofill: true, ... },
Is there some way to get a selector on MyEmailInput whose input.name property is "workEmail" ? I can't figure out if it is possible or what the syntax would be.
For now I am using cy.get("input[name=workEmail]")
but then I'm not really exercising the React model, but more the HTML output.
In the example in the readme file you have this:
// validate the property runtime
cy.getReact('MyTextInput', { props: { field: { name: 'email' } } })
.getProps('fields.value')
.should('eq', '[email protected]');
but where did fields.value
come from?
Hi Abhinaba,
I have updated my Cypress.json file with the env for cypress-react-selector. I am getting error, while inspecting Component using React-Dev tool. Multiple reasons error.
Component not found <* name="tradition">
There can be multiple reasons for it.
Check the root is defined as a env parameter (cypress.json config file).
If the root is defined correctly, check other parameters - component name, props and state objects
cy.waitForReact();
const btn = cy.react('Anonymous*', { props: { name: 'abc' } });
//const btn = cy.react('CatalogGridItem*', { props: { name: 'xyz' } });
btn.click();
I am writing End to end tests and doesn't have access to source code, so is there any way to get the component name from React dev tool which I can use in my test scripts using Cyrpess-react-selector.
Any tests that depend on cypress-react-selector
consistently fail in GitLab CI. A simple test that passes locally but fails in CI is:
describe("Header", () => {
beforeEach(() => {
cy.waitForReact();
});
it("is visible", () => {
cy.react("DashboardHeader").should("be.visible");
});
});
Selecting by element ID works as expected. I've tried using Chromium instead of Electron in CI and that had no effect. I consistently get the following error:
Timed out retrying; Expected to find element:
undefined
, but never found it.
Currently supported properties to be queried are props
, state
, and exact
. Thow error, if other properties are used.
This line completely breaks monorepo setup. In case node_modules are hosted somewhere upper. Please replace this with require
.
Hello! I'm trying to use function getProps()
on GridItem
component which comes from this package React-grid-layout, however it returns undefined.
My usage looks like this
cy
.react('GridItem', { i: 'evaluation' })
.getProps()
it will be nice to mounting react component runtime so that user can update states and props runtime.
Something like:
cy.getReact().setProps({})
cy.getReact().setState({});
I'm trying to assert that there are 0 AccountCards on the page.
cy.react("AccountCard").should("not.exist")
throws:
Component not found <AccountCard>
So, it's correct - the component is not found. However, I would expect for the assertion to pass, not fail.
cy.react("AccountCard").should("have.length", 0);
runs into a similar issue.
Test:
describe("Search input", () => {
beforeEach(() => {
cy.visit("/");
cy.waitForReact();
});
context("viewport width === 640", () => {
it("is visible", () => {
cy.viewport(650, 1_024);
cy.react("DashBoardHeader").should("be.visible");
});
});
});
cypress.json
{
"pluginsFile": false,
"supportFile": false,
"baseUrl": "http://localhost:8080",
"env": {
"cypress-react-selector": {
"root": "#root"
}
}
}
error:
assert
expected { Object () } to be visible
4
then
function(){}
CypressError
cy.then() timed out after waiting 4000ms.
Your callback function returned a promise that never resolved.
The callback function was:
(window) => {
const isPrimitive = (x) =>
Cypress..isNumber(x) || Cypress..isString(x) || Cypress._.isBoolean(x);
const getNodes = () => {
let elements;
if (!window.resq) {
throw new Error(
'[cypress-react-selector] not loaded yet. did you forget to run cy.waitForReact()?'
);
}
if (subject) {
elements = window.resq.resq$(component, subject[0]);
} else {
if (getReactRoot(reactOpts.root) !== undefined) {
elements = window.resq.resq$(
component,
document.querySelector(getReactRoot(reactOpts.root))
);
} else {
elements = window.resq.resq$(component);
}
}
if (reactOpts.props) {
elements = elements.byProps(reactOpts.props);
}
if (reactOpts.state) {
elements = elements.byState(reactOpts.state);
}
if (!elements.length) {
return null;
}
let nodes = [];
elements.forEach((elm) => {
var node = elm.node,
isFragment = elm.isFragment;
if (isFragment) {
nodes = nodes.concat(node);
} else {
nodes.push(node);
}
});
return nodes;
};
const resolveValue = () => {
return new Cypress.Promise.try(getNodes).then((value) => {
if (!isPrimitive(value)) {
value = Cypress.$(value);
}
return cy.verifyUpcomingAssertions(value, options, {
onRetry: resolveValue,
});
});
};
return resolveValue()
.then((value) => {
return value;
})
.catch((err) => {
throw new Error(
getComponentNotFoundMessage(
component,
reactOpts.props,
reactOpts.state
)
);
});
}Learn more
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.