Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to select single component from multiple on page #41

Closed
claytron5000 opened this issue Sep 9, 2020 · 25 comments
Closed

How to select single component from multiple on page #41

claytron5000 opened this issue Sep 9, 2020 · 25 comments
Labels
bug Something isn't working

Comments

@claytron5000
Copy link

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?

@abhinaba-ghosh
Copy link
Owner

Hi @claytron5000 , thanks for raising the query. You wanna look into the chained command section: https://github.com/abhinaba-ghosh/cypress-react-selector#use-fluent-chained-queries

Let me know if that does not work. I will be happy to dig into that.

@abhinaba-ghosh abhinaba-ghosh added the question Further information is requested label Sep 9, 2020
@claytron5000
Copy link
Author

That's exactly it. I was getting an error, but I think it was a bad selector. Thanks for the cool tool!

@abhinaba-ghosh
Copy link
Owner

Hi @claytron5000, when I created the tool, I actually tested against a smaller set of use cases. It is also possible that the error you are getting is a valid error and I missed to handle that very logic. If you get the error, again and again, I request you to re-open the ticket and help me to get it resolved.

Thanks a lot again for giving a try with the tool. :)

@abhinaba-ghosh
Copy link
Owner

also, not, fluent chained commands dot really re-try. I am working on it to get it resolved.

#30

@claytron5000
Copy link
Author

Yeah, it looks legit.

cypress.json:

{
    "pluginsFile": false,
    "supportFile": false,
    "baseUrl": "http://localhost:8080",
    "env": {
        "cypress-react-selector": {
            "root": "#root"
        }
    }
}

Test code:

describe("Search input", () => {
	beforeEach(() => {
		cy.visit("/");
		cy.waitForReact();
	});

	context("viewport width === 640", () => {
		it("is visible", () => {
			cy.viewport(640, 1_024);
			cy.react("Search").react("SvgIcon").should("be.visible");
			
		});
	});
});

React code:

function Search() {
	const classes = useStyles();

	return <Box component="form" width="100%" color="text.secondary">
		<TextField InputProps={{
			startAdornment: <InputAdornment position="start"
			className={classes.inputAdornment}>
				<Box p={1.5}>
					<SearchIcon fontSize="small" />
				</Box>
			</InputAdornment>,
			classes: {
				input: classes.input,
				formControl: classes.formControl,
			},
			disableUnderline: true,
		}}
		className={classes.textField}
		placeholder="Search school, city, state &amp; teams..."
		inputProps={{"aria-label": "search"}} />
	</Box>;
}

The SearchIcon is a MaterialUI svg icon that's transformed into SvgIcon. Here's the component tree screenshot:

image

@claytron5000 claytron5000 reopened this Sep 9, 2020
@abhinaba-ghosh
Copy link
Owner

Hey @claytron5000 Thanks for re-opening and for the logs. Would you mind also sharing the cypress window error messages? Screenshot will be enough. I want to see the waiting period and the messages it is producing.

@abhinaba-ghosh abhinaba-ghosh added bug Something isn't working and removed question Further information is requested labels Sep 9, 2020
@claytron5000
Copy link
Author

claytron5000 commented Sep 10, 2020

I don't see the waiting period.

Component not found <SvgIcon>


  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:89:1
  87 |       })
  88 |       .catch((err) => {
> 89 |         throw new Error(
     | ^
  90 |           getComponentNotFoundMessage(
  91 |             component,
  92 |             reactOpts.props, 
View stack trace
 Print to console
    at eval (webpack:///node_modules/cypress-react-selector/src/reactHandler.js:89:1)
From previous event:
    at getRet (http://localhost:8080/__cypress/runner/cypress_runner.js:154850:21)
From previous event:
    at Context.thenFn (http://localhost:8080/__cypress/runner/cypress_runner.js:154868:27)
    at Context.then (http://localhost:8080/__cypress/runner/cypress_runner.js:155308:22)
    at Context.<anonymous> (http://localhost:8080/__cypress/runner/cypress_runner.js:168808:22)
    at <unknown> (http://localhost:8080/__cypress/runner/cypress_runner.js:168241:16)
From previous event:
    at runCommand (http://localhost:8080/__cypress/runner/cypress_runner.js:168220:9)
    at next (http://localhost:8080/__cypress/runner/cypress_runner.js:168366:15)
    at <unknown> (http://localhost:8080/__cypress/runner/cypress_runner.js:168394:17)
From previous event:
    at next (http://localhost:8080/__cypress/runner/cypress_runner.js:168366:35)
From previous event:
    at <unknown> (http://localhost:8080/__cypress/runner/cypress_runner.js:168407:38)
From previous event:
    at run (http://localhost:8080/__cypress/runner/cypress_runner.js:168400:20)
    at $Cy.cy.<computed> [as viewport] (http://localhost:8080/__cypress/runner/cypress_runner.js:168852:12)
    at Context.runnable.fn (http://localhost:8080/__cypress/runner/cypress_runner.js:169078:22)
    at callFn (http://localhost:8080/__cypress/runner/cypress_runner.js:103957:22)
    at Test.../driver/node_modules/mocha/lib/runnable.js.Runnable.run (http://localhost:8080/__cypress/runner/cypress_runner.js:103944:8)
    at <unknown> (http://localhost:8080/__cypress/runner/cypress_runner.js:174727:29)
From previous event:
    at Object.onRunnableRun (http://localhost:8080/__cypress/runner/cypress_runner.js:174715:21)
    at $Cypress.action (http://localhost:8080/__cypress/runner/cypress_runner.js:165051:62)
    at Test.Runnable.run (http://localhost:8080/__cypress/runner/cypress_runner.js:173050:14)
    at Runner.../driver/node_modules/mocha/lib/runner.js.Runner.runTest (http://localhost:8080/__cypress/runner/cypress_runner.js:104616:11)
    at <unknown> (http://localhost:8080/__cypress/runner/cypress_runner.js:104742:13)
    at next (http://localhost:8080/__cypress/runner/cypress_runner.js:104525:15)
    at <unknown> (http://localhost:8080/__cypress/runner/cypress_runner.js:104535:8)
    at next (http://localhost:8080/__cypress/runner/cypress_runner.js:104437:15)
    at <unknown> (http://localhost:8080/__cypress/runner/cypress_runner.js:104503:6)
    at timeslice (http://localhost:8080/__cypress/runner/cypress_runner.js:98429:28)

@abhinaba-ghosh
Copy link
Owner

Hi @claytron5000, can you try upgrading to v2.1.0 and retrying the same commands. I have added some extra retry mechanism recently. Would love to get the feedback.

@mjc4thewin
Copy link

mjc4thewin commented Oct 23, 2020

@abhinaba-ghosh I'm getting the same issue on version 2.2.0.

Error: Component not found
cypress |
cypress |
cypress | There can be multiple reasons for it.
cypress |
cypress | > Check the root is defined as a env parameter (cypress.json config file).
cypress |
cypress | > If the root is defined correctly, check other parameters - component name, props and state objects
cypress |
cypress |
cypress | Or, raise an issue with proper code samples here: https://github.com/abhinaba-ghosh/cypress-react-selector/issues
cypress | at eval (http://client:3000/__cypress/tests?p=cypress/support/index.js:298:15)

Here is my config:

{
  "baseUrl": "http://localhost:3000",
  "env": {
    "cypress-react-selector": {
      "root": "#root"
    }
  }
}

Strangely, this only happens when I run inside a docker container. When I run the tests locally it finds the component just fine and all tests pass.

Here's what I'm trying to do in my test...

cy.visit('/my-page')
cy.waitForReact();
        
cy.react('MyComponent')
   .find('h3')
   .should('have.text', 'Hello World');

@abhinaba-ghosh
Copy link
Owner

abhinaba-ghosh commented Oct 27, 2020

@zRealMikeJordan, The library works irrespective of the underlying infrastructure. So, if it is working in your local, not in the docker, there is a high chance that the application under test has been changed. Are you building the react app for production and testing it in the docker? Sometimes, it changes the component names. Try building in profile mode

@mjc4thewin
Copy link

mjc4thewin commented Oct 27, 2020 via email

@abhinaba-ghosh
Copy link
Owner

Hey @zRealMikeJordan , good to know that you figured out the issue. This can help to get some idea about the profiling mode.

@caseyjhol
Copy link

caseyjhol commented Oct 30, 2020

@abhinaba-ghosh Thanks for all of your work on this! Unfortunately, chained commands still aren't working for me. I have two MenuButton components on my page; one is inside the DashboardFooter component (the one I want to target).

describe("Sidebar", () => {
	beforeEach(() => {
		cy.waitForReact();
	});

	it("opens sidebar on click", () => {
		cy.react("DashboardFooter").react("MenuButton").click();
	});
});

returns

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.

image

Only one MenuButton is visible at any given time. After investigating further using .first() and .last(), I confirmed that it's selecting both the visible and the invisible buttons, meaning it's behaving exactly as if I wasn't including cy.react("DashboardFooter") at all.

Cypress v5.5.0
cypress-react-selector v2.2.0
My cypress.json:

{
    "pluginsFile": false,
    "baseUrl": "http://localhost:8080",
    "env": {
        "cypress-react-selector": {
            "root": "#root"
        }
    }
}

@abhinaba-ghosh
Copy link
Owner

@caseyjhol I will have a look into this.

@abhinaba-ghosh
Copy link
Owner

Hi, just catching up on things. I have created this repository to reproduce this bug. I am digging in. I will update the progress here.

@abhinaba-ghosh
Copy link
Owner

abhinaba-ghosh commented Nov 15, 2020

A dependent ticket has been created in resq module to track.
baruchvlz/resq#73

@baruchvlz
Copy link

baruchvlz commented Nov 17, 2020

This not being able to find React issue seems to be related to some changes in the way React attaches the FiberNodes to the elements. The release RESQ v1.10.0 should fix it.

Now, as to the chain operations. This is not supported in RESQ and should be handled at a library level. One of the ways to do this, is to do resq.waitToLoadReact() on every call of cy.react.

@abhinaba-ghosh
Copy link
Owner

Thanks for the input @baruchvlz .
Much appreciated. Once the resq release is available, i will update this library to tackle the waitForReact calls.

@abhinaba-ghosh
Copy link
Owner

This not being able to find React issue seems to be related to some changes in the way React attaches the FiberNodes to the elements. The release RESQ v1.10.0 should fix it.

Now, as to the chain operations. This is not supported in RESQ and should be handled at a library level. One of the ways to do this is to do resq.waitToLoadReact() on every call of cy.react.

hi @baruchvlz , I have a different thought here. I don’t think you need to call waitToLoadReact every time internally in cy.react calls. Once React loading established, It will return - React already loaded, no matter how many times you run it. Now, in the case where AUT reloads the window, yes, you need to re-establish the react loading, not for all. I successfully manage to chain query by providing incoming ReactElement in the resq$$(component, reactElement) command for this react example. But, for a different app, it is showing wired behavior and logged here - baruchvlz/resq#76

@frysztak
Copy link

hi @abhinaba-ghosh, have you made any progress on this?

@abhinaba-ghosh
Copy link
Owner

@Hey @frysztak , we are getting few hiccups for React 17. I will work on this over the upcoming weekend. But, PR is always welcome.

@frysztak
Copy link

@abhinaba-ghosh I'd gladly help, though I'm not sure where to start. could you point me in the right direction?

@abhinaba-ghosh
Copy link
Owner

@abhinaba-ghosh I'd gladly help, though I'm not sure where to start. could you point me in the right direction?

@frysztak You can look into this to get the ground baruchvlz/resq#76

@frysztak
Copy link

hello again @abhinaba-ghosh, I finally took a look at your repo. chained queries don't work for React 16 as well. and seeing that this issue was created before React 17's release - it doesn't seem like it has anything to do with it

@abhinaba-ghosh
Copy link
Owner

abhinaba-ghosh commented Nov 2, 2021

This is now fixed with version 2.3.13 ( #251 )

Example - https://github.com/abhinaba-ghosh/cypress-react-chain-queries

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

6 participants