Facing cors issue in Cypress while switching the domain - cypress

Hi i am facing the common CORS issue with cypress using the Okta login. Below is the sample code snippet.
it('Login', () => {
cy.visit("https://example.com/landing")
cy.wait(3000);
cy.get('.btn').click(); //clicks on Signin button
//switches to other domain.
cy.origin('https://login.xyz.com', () => {
});
The login url further get navigated along some parameters line ProductID,OAuthCode,ClientID and locale.
While running the test the page do gets successfully redirected to desired URL after Signin button is clicked, however immediately in the next step it gets reverted to the URL mentioned in the cy.origin and hangs in there.
In the Cypress.config.js i have also set:
"chromeWebSecurity": false,
"experimentalSessionAndOrigin": true
Is there a way i can get down to the Sign page and pass on the credentials to move further.

Related

Request to Google OAuth endpoint redirects to a blank page in Firefox

I have a React (CRA) + Node JS application already deployed locally (using the create-react-app build script), I've implemented Google OAuth signin with passportjs and cookieSession for persistence.
The login works fine but there is a strange bug when I Logout and then try to log in again with google OAuth, it just redirects me to a blank page.
This is how I make the request to my google oauth endpoint:
window.open('https://localhost:3000/auth/google', "_self")
That endpoint then is taken by my API:
app.get('/auth/google', passport.authenticate('google', { scope: ['profile', 'email'] }));
Doing some troubleshooting it seemed at first the culprit were the cookies because when I delete the site data before trying to login again... then the login works just fine.
However if I delete the cookies only (through the storage panel -> cookies -> delete all, in firefox) the bug still persists, it only disappears when I delete the site data entirely.
Moreover, The second time I try to login the request don't event reach my server.
What I've alredy tried:
Wrapping my login button inside an anchor tag and setting the anchor's tag href to the endpoint url.
Creating an anchor tag and assigning an href with the endpoint url and then clicking that new element programmatically.
None of this worked, the issue still persists.
Fresh firefox profile: this is even weird, the bug appears the very first time I try to login with google in a newly created profile. Again I have to first click the clear cookies and site data button for it to work.
Incognito mode: The issue persists, again the first time I login it works but the second time it redirects me to a blank page and the request is not even reaching my server.
What could be the problem here?
The issue was the service worker that cames with the creat-react-app template, however I didn't want to disable it completely as I want my app to be a PWA, so the next best thing was to disable the service-worker caching specifically for the page from which the user initiates the Google login (the page where the google button is).
For this I had to install the sw-precache package which allows you to modify the default service-worker that came with the create-react-app template (as you cannot directly modify it).
Then you have to create a config file at the root of your project and add these lines, in this case I call it sw-precache-config.js:
module.exports = {
runtimeCaching: [
{
urlPattern: /<the route to ignore>/,
handler: 'networkOnly'
}
]
};
and then in the build script from your package json:
"build": "react-scripts build && sw-precache --config=sw-precache-config.js"

Why can't I log in to Cypress?

I am new to Cypress, I write different test cases in Cypress, my first case is that I want to login to the website, then do other activities. One thing in particular, in practice it should see the user login.
so i am expalin my case here,
before(function () { EITHER write login code here.....}) OR
create one case like it('Login',()=>{login code here.....})
then after create our required test cases after above IT block.
ex.
it('Login', ()=>{
//USER LOGIN CODE...
})
it('Dashboard', ()=>{
//Dashboard CODE...
})
it('Contact Us', ()=>{
//Contact Us CODE...
})
once the first case executes, the user can be logged in to the system, then after redirect on DASHBOARD, we click on the CONTACT US link/menu, and then the CONTACT US page is open where we can perform our operation.
Issue-
in my case, I had tried both the way before and separately IT block, every time if we click on CONTACT US page then redirect on Login page again.
and show the message on the log section-
-get#linkConactus > a
-click
-(new url)https://example.com/admin/dashboard
-(new url)https://example.com/login
This is my case-
I am confused Here i am sharing actual scenario with code.
///
describe('Dashboard Page', function () {
it('login',function () {
cy.visit('https://opensource-demo.orangehrmlive.com/');
cy.get('#txtUsername').type('Admin');
cy.get('#txtPassword').type('admin123');
cy.get('#btnLogin').click();
cy.get('#welcome').contains('Welcome');
})
it('Verify Dashboard Text', () => {
cy.wait(2000);
cy.log("this is Dashboard Page.............");
let extText='Dashboard';
cy.get('.head > h1').then((txt) =>{
let act_txt=txt.text();
cy.log('Actul Text is= '+ act_txt);
expect(extText).to.eq(act_txt);
})
})
it('My Leave Page', () => {
cy.log('My Leave Page is Open..........')
cy.get(':nth-child(5) > .quickLaunge > a > .quickLinkText').click();
//Issue facing on above line while I am click on next Menu like 'My Leave' then redirect to login Page.
let extText='My Leave List';
cy.contains('My Leave List').then((txt) =>{
let act_txt=txt.text();
cy.log('Actul Text is= '+ act_txt);
expect(extText).to.eq(act_txt);
})
})
})
I'll guess you don't have mocked all network requests correctly. Because a redirect to the login page should only happen, if the user is not authenticated. Maybe you webapp makes a network request, that fails and then redirects you to the login page.
Maybe try the following testing strategy, if you a newer. Because in Cypress you should always try to mock the network requests to your api with cy.intercept
Login page test
Create a seperate test file for this one.
You visit the login page, fill out the information and mock all request, that are made to your api with cy.intercept. Then press the login button. Now the test should login into your webapp without making any requests to your api.
All other pages
Create a cypress command and name it like mockLogin. There you should setup all auth tokens in your local storage and mock the requests for validating this token. With that you can simulate as if the user is logged in and just revisits your webapp.
Now you can execute that command in every beforeEach() for your other pages. That way you are logged in in all of your tests, without manually loggin in for each test case.
In Cypress version 12 a new change was introduced: by default testIsolation is true (see below) so if you have tests dependent of other tests, set that variable to false in your cypress.config file.
https://docs.cypress.io/guides/core-concepts/writing-and-organizing-tests#Test-Isolation

cypress unable to click login button. getting Post error

New to cypress. Getting error in cypress login click.
it('Should Login', () => {
cy.get('#ctl00_ContentPlaceHolder1_m_btnSubmit').click()
})
Error Screenshot
The error you have is coming from the app itself, it looks like the login is failing.
You set credentials user name and password before login, and the screenshot shows a previous test where password is entered.
Try combining all the login steps into one test. Cypress does a lot of clearing of data between tests to make them independent, so each test should be an "atomic" action, for example
it('Should Login', () => {
cy.get('#username').type('myusername')
cy.get('#password').type('mypassword')
cy.get('#ctl00_ContentPlaceHolder1_m_btnSubmit').click()
})

Signin request failing due to invalid csrf

I am testing a signin page for keystonejs (http://demo.keystonejs.com/) and cannot get the request to succeed with cypress. A signin request without cypress has the following request headers:
while a request with a cypress test has the following request headers:
The only difference I can see is that the cookie is not set in the cypress test request. And because of that the request gets a 403. I am actually using a local version of that server in which I have the email/password configured as the one in the images. The demo site uses a different set provided in that page.
The test is simply:
describe('The Keystone Admin UI Signin Page', function () {
before(function() {
cy.visit('http://localhost:3000/keystone/signin')
})
it('should signin successfully with valid email/password', function () {
cy.get('#signin-view input[name=email]').clear().type('user#test.e2e');
cy.get('#signin-view input[name=password]').clear().type('test');
cy.get('#signin-view button[type=submit]').click();
cy.get('#react-root').should('be.visible');
})
})
Anyway to get around this?
I know this is an older question but I'll post this in case it helps anyone.
The key to fixing this issue for me was that Cypress clears all cookies before each test (https://docs.cypress.io/api/commands/clearcookies.html#).
So in the example above (and in my experience):
The first test (loading the page) is run and passes fine - at this point the browser has set the csrftoken cookie
The second test (submitting the form) runs but before this happens Cypress has deleted the csrftoken cookie - hence the error
To fix this I had to whitelist the csrftoken cookie in Cypress config which means that it will be exempt from this clearing process:
Cypress.Cookies.defaults({
whitelist: "csrftoken"
})
You can do this inline in your test file but the docs recommend using a support file:
A great place to put this configuration is in your cypress/support/index.js file, since it is loaded before any test files are evaluated.
Hope this helps, Stephen.
Following on from FlatSteve's answer, using with Laravel and updated prop names use;
Cypress.Cookies.defaults({
preserve: ["XSRF-TOKEN", "your_laravel_session_name", "remember_token"]
});

Facebook cookie retained until manual referesh

I'm building a PHP site that uses Facebook OAuth as the login mechanism. The problem is that when the user logs out and is directed back to my site, the site is still effectively logged (at least in appearance) in until the user manually refreshes the page.
I suspect the reason for this is because the Facebook cookies are removed only once the return page has finished rendering. I accept I'm not fully versed in the way sessions work.
User logs out
-> Redirect to Facebook
-> Redirect back to site (logout.php)
-> Clear local session
-> Redirect to home page (index.php)
-> Page renders (still logged in)
-> Cookies removed
-> Manual refresh (index.php)
-> Page renders (no longer logged in).
I had a similar issue with an ASP.NET MVC site a little while ago. My fix then was to parse the page with JavaScript after the page had loaded and once the cookies had finally been removed.
I am working on the assumption that I'm doing something wrong. I simply want index.php to recognise that Facebook is logged out without having to refresh.
I use header() to redirect from logout.php to index.php.
header("Location: index.php");
EDIT:
I have tried appending the current time to the redirect url in order to side step caching problems. This has not helped.
EDIT:
Watching cookie activity in FireCookie backs up my suspision that the Auth cookie is removed after the page is rendered. This is obviously not conclusive as FireCookie doesn't show me what's happening server side.
JS Workaround:
My current workaround is to run the following snippet on page load, where $fbUid is the Facebook User ID. It's not ideal though, because it relies on JavaScript.
FB.getLoginStatus(function(response) {
if (<?php echo $fbUid ? "true" : "false" ?> && response.session == null)
window.location.reload();
});
Rich
Probably a cacheing issue. Add some randomly generated value to the query string in the redirect, so it'll appear as a "new" page to the browser, something like:
header('Location: index.php?cachebuster=' . microtime(true));
That should force the browser to fetch a fresh copy, which would then not have the "logged in" content anymore.
Cracked it with help from Delete facebook session cookie from my application on users logout and the SDK source.
Adding this code snippet to the logout page ensures that the authentication is properly removed.
$facebook = new Facebook(array(
'appId' => FB_APP_ID,
'secret' => FB_SECRET,
'cookie' => true,
));
$fbCookieName = 'fbs_' . $facebook->getAppId();
$domain = $facebook->getBaseDomain();
if ($domain) {
$domain = '.' . $domain;
}
setcookie($fbCookieName, '', time() - 3600, '/', $domain);
$facebook->setSession();
The code empties the cookie and expires it at the same time. The session is then explicitly removed.
Rich
hi i have same this issue but i resolve this issue
buy using this
FB.Event.subscribe('auth.login', function(response) {
window.location.reload();
});
FB.Event.subscribe('auth.logout', function(response) {
window.location.reload();
});
please add this script where you have to write your login code. and enjoy

Resources