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

Cypress v12 version doesn't allow me to use req.alias in an interceptor (using graphql) #25210

Closed
damocles217 opened this issue Dec 19, 2022 · 14 comments

Comments

@damocles217
Copy link

damocles217 commented Dec 19, 2022

Current behavior

Hi, I have an issue when I try to excecute a interceptor using graphql queries, but when I want to modify the request alias, it doesn't happen.

this bug happens whether I follow the documentation (what I did) or try other possible solutions.
And when I use the 'as' method, this doesn't occur. But the query isn't tracked by cypress.

Desired behavior

In this case, cypress should add an alias to the graphql query, but it doesn't happen

Test code to reproduce

The code I implemented is the next:

export const hasOperationName = (req, operationName) => {
	const { body } = req;
	return (
		body.hasOwnProperty('operationName') && body.operationName === operationName
	);
};

export const aliasQuery = (req, operationName) => {
	if (hasOperationName(req, operationName)) {
		req.alias = `gql${operationName}Query`;
	}
};

export const aliasMutation = (req, operationName) => {
	if (hasOperationName(req, operationName)) {
		req.alias = `gql${operationName}Mutation`;
	}
};


describe('Cart shop page', () => {
	beforeEach(() => {
		cy.intercept('POST', 'http://localhost:5000/api', (req) => {
			aliasQuery(req, 'getCategories');
		});

		cy.visit('http://localhost:3000/start');
	});

	it('Must render the start page and, after that, continue with the payment cycle', () => {
		cy.wait('@gqlgetCategoriesQuery');
		cy.contains(/2/g).click();
		cy.get(
			':nth-child(4) > .GenericCategoriesCard_Container_Card__3FBa3 > .MuiPaper-root > .MuiCardMedia-root'
		).click();

		// cy.wait('@gqlgetTBQuery');
		cy.get(
			':nth-child(1) > .MuiPaper-root > .showMobile > .GenericCategoriesCard_add_button__3P54V'
		).click();
	});
});

Cypress Version

12.1.0

Node version

18.12.1

Operating System

Arch Linux. Kernel Version 6.0.11

Debug Logs

No response

Other

I tried to use a global variable to see what's wrong, and when I print it is like the variables couldn't be modifiied into the (req) => {...} function

@j1000
Copy link

j1000 commented Dec 20, 2022

I wonder if there's a general problem with aliases right now. I had to revert back to v11 because my aliases would completely lose their value.

@nagash77
Copy link
Contributor

possibly related to #24653

@damocles217
Copy link
Author

@j1000 I'll try it, and so, I'll post it in this issue, thank you

@damocles217
Copy link
Author

@nagash77 in fact, I saw that issue before writte this, but it doesn't fix my problem.

@lmiller1990
Copy link
Contributor

lmiller1990 commented Dec 23, 2022

I tried to reproduced this - no luck so far, here's my example (not minimal, but using GraphQL and alias): https://github.com/lmiller1990/eleutheria/compare/repro-25210?expand=1.

Seems there is a UI bug - it says "no alias" which is wrong, but I was able to intercept it.

@damocles217 what was your last working version of Cypress? That would help minimize the surface area.

image

@lmiller1990
Copy link
Contributor

I made my example more similar, but I still did not reproduce:

describe("authentication flow", () => {
  beforeEach(() => {
    cy.clearCookies();

    cy.intercept("POST", "http://localhost:5566/graphql", (req) => {
      if (req.body.operationName === 'Profile_Viewer') {
        req.alias = "foo";
      }
    });
  });

  it("signs up", () => {
    cy.visit("/app");

   // ... fill out form ...

    cy.get("button").contains("Submit").click();

    cy.get('[data-cy="authenticate"]').click();

    cy.wait("@foo"); // works!
  });
});

Has anyone else had luck reproducing this in a minimal fashion?

@damocles217
Copy link
Author

@lmiller1990 really? Okey, I'll try, but I tried to save the value in a higher scope and print, the result was undefined. So, I don't know what happen. Let me give you more information in few time, because I did what you do, and doesn't works anyway.

@lmiller1990
Copy link
Contributor

lmiller1990 commented Dec 23, 2022

I made a minimal reproduction with GraphQL and a dynamic alias, but it's passing for me:

https://github.com/lmiller1990/cypress-issue-25210/blob/main/cypress/e2e/spec.cy.js

To intercept the GraphQL I had to do

cy.intercept("POST", "http://localhost:4000/graphql*", req => {

With a *, but that might be because my app passes a query string to the request. Can you do a console.log and verify it's actually going into the code where the alias is set @damocles217? Also, if you think this is a regression, please share the version of Cypress where it's working as expected.

@lmiller1990
Copy link
Contributor

lmiller1990 commented Dec 23, 2022

Oh you know what it might be @damocles217, you are using cy.contains(...). There was a bug with that, that is fixed here: #25250

Potentially related? Just a stab in the dark, could be unrelated.

@damocles217
Copy link
Author

I tried now and works, but is something very strange, because I tried the same thing yesterday and some days before and this doesn't work. In this case I'm working directly with the function, as you did ti @lmiller1990 with the character * at the end of the url string

describe('Login page', () => {
	beforeEach(() => {
		cy.visit('http://localhost:3000');
		cy.intercept('POST', 'http://localhost:5001/api*', (req) => {
			if (req.body.operationName === 'getAllData') {
				console.log('Im in node');
				req.alias = 'node';
			}
			if (req.body.operationName === 'login') {
				console.log('Im in mainnet');
				req.alias = 'mainnet';
			}
		});
	});

	it('Must render the initial state of the page', () => {
		const inputNames = ['email', 'password'];

		const inputValues = ['admin@google.com', 'admin123'];

		cy.contains(/Iniciar sesión/gi);

		inputNames.forEach((name, index) => {
			cy.get(`[name="${name}"]`).type(inputValues[index]);
		});

		cy.get('.btn').click();
		cy.wait('@mainnet')
			.its('response.body.data.loginV2')
			.should('have.property', 'ok');
		cy.wait('@node')
			.its('response.body.data.getAllData')
			.should('have.length', 4);
	});
});

Now to rewrite every test, thank you!

@lmiller1990
Copy link
Contributor

@damocles217

Now to rewrite every test, thank you!

Can you explain a bit more? If we had a regression, you don't have to rewrite your tests - we will fix the bug.

My question is - did you find the problem? Was that exact code working in an old version? If so, which one?

@damocles217
Copy link
Author

damocles217 commented Dec 26, 2022

@lmiller1990 I was talking about I did some 'tricks' for doing my tests, because they didn't work.

Response: yes, what I did is write the code you gave me:

cy.intercept('POST', 'http://localhost:5001/api*', (req) => {

This line solved the problem for this version, I didn't try to do it in an old version, but I'll do it, and I'll write again over this issue.

The problem, or I guess, is cypress doesn't recognizes this '/' by itself, it needs '*' after the slash

@lmiller1990
Copy link
Contributor

Yeah, it looks like cy.intercept('POST, 'http://localhost:5001/api') matches exactly that. So, you need the wildcard.

Let me know if you need any more help or run into any other issues with aliases or GraphQL.

@damocles217
Copy link
Author

@lmiller1990 that's all over this issue, thank you guy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants