Why can't I log in to Cypress? - 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

Related

Facing cors issue in Cypress while switching the domain

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.

Cypress, how do you visit two different domains for a single test?

I have the following:
describe('Page not authenticated', () => {
it('Page has authentication', () => {
cy.visit('https://myauthsite.com/logout');
cy.visit('/', { failOnStatusCode: true });
cy.url().should('include', 'https://myauthsite.com/');
});
})
For internal reasons, the package is set up so that it always has a persistent session, so I need a test to visit a specific URL that would explicitly logout and "kill" the session and then visit the main page that I'm trying to test to ensure that it does redirect me to the right page. However, I'm running into this error
You may only `cy.visit()` same-origin URLs within a single test.
The previous URL you visited was:
> 'https://myauthsite.com'
You're attempting to visit this URL:
> 'https://myactualsite.com'
You may need to restructure some of your test code to avoid this problem.
https://on.cypress.io/cannot-visit-different-origin-domain
A lot of the workarounds that's listed mostly addresses checking for the attribute instead of visiting the url, or splitting the visits into two different test case, but in my case I really need it to be in its own encapsulated test, is that not possible?
cy.request() isn't bound by the same cross-origin request policies, so if you can log out via an HTTP request that should work.
I tried using chromeWebSecurity=false, but that didn't help.
I'm currently using the API login, setting the cookies, and later read "Google Sign in with Cypress"''
cy.request({
method:"POST",
url:API_URL,
headers: {
'Content-Type': 'application/json',
},
body: api_body}).then((response =>{
cy.log(response.body)
cy.setCookie("token_name",response.body['token']);
cy.visit(destination_url);
}))
API_URL is your API login URL:
token_name: Login manually to UI, Using the web developer tool you can get the required token_name
This resolved my multi-domain login issue, and you can use it for multi-domain navigation.

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()
})

Creating database entries in Exist-DB with Ajax calls

While developing a self-contained exist-db app I ran into some issues with passing on the user's identity during an ajax call.
I have created a standard page that allows the user to login in with his or her standard exist-db account. (It's more or less based on this https://github.com/eXist-db/existdb-login ).
At some point, the users need to create their own entries and upload files, and this is done with an ajax script (I'm using Kartik's bootstrap uploader, but it's basically a standard ajax upload function):
$('#input-24').fileinput({
uploadUrl: "../modules/uploader.xql",
uploadAsync: true,
fileActionSettings : {
uploadExtraData() {
return {
'FileName': $(this).data('title'),
}
}
},
});
Now, of course, this will fail, since it will appear like a GUEST user is trying to create entries, which is an action that is allowed only for registered users.
Does exist-db allow a way to send in my login credentials at this point without having to resort to the standard HTTP login (which is problematic, since it means creating a cookie to memorize the password, which more or less renders the whole login suing exist's mechanisms useless), or is there any way to use the controller instead of an external script?
Thanks in advance!
I think you can add the user and password into the URI to trigger the Ajax client to do basic with. e.g. http://username:password#your-server/some/uri/modules/uploader.xql
For simple, basic authentication we do the following since the page itself is being served from xQuery.
step 1: we create in the page xQuery a variable containing the session info. This should be fine for you ... the result of your login would be an HTML page:
let $sessinfo := util:base64-encode(concat(request:get-parameter('user', ()), ":", request:get-parameter('pass', ())))
step 2: during the build of the result page in xQuery, we turn that into a javascript variable through a simple script command placed in <head> tag:
<script>
var sessinfo = "{$sessinfo}";
</script>
step 3: in Javascript loaded with the page (we use jQuery), after the page is ready we setup authentication for all AJAX requests:
jQuery.ajaxSetup({
headers: {
"Authorization": "Basic " + sessinfo
}
});
After that, any AJAX request made would send basic authentication header with user and password to other xQueries executed with jQuery.ajax
To have an eXistdb session work with XHR (Ajax requests) you need make sure that
login:set-user('my.login.domain', (), false())
is called in the controller before you forward it to your request handler. Otherwise all request will seem to originate from the 'guest' user.
If you want to use vanilla/native JavaScript requests e.g. fetch you also need to tell it to add the credentials to the request:
fetch(url, { credentials: 'same-origin', method: 'GET' })
By the way, the persistent login used in exidtb-login likely uses a cookie value to pick up the session variables stored on the server (JSESSIONID), but I need to check that.

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"]
});

Resources