(uncaught exception)TypeError: $(...).datepicker is not a function - testing

it('Access URL', () => {
cy.visit('URL')
cy.wait(5000)
cy.get('.login-btn').click()
})
URL is working but login click is not working.
(uncaught exception)TypeError: $(...).datepicker is not a function --- is displayed
Trying to access url and trying to click the Login link in the website.

If it takes the page more then 5 seconds to load cypress would never find the button in your code. If you can give the button an id it would be able to find it, but if you can't you can try to add a long timeout to the button and when the button appear on the page it will click it, for example.
`cy.get('.login-btn', { timeout: 30000 }).click()`

By the looks of your comment, you have an uncaught exception in your application. That’s an indication you or a dev needs to fix something in the app. Cypress is just trying to tell you.
If you want to ignore the error, you can add this to your test
it('Access URL', () => {
cy.once('uncaught:exception', () => false);
cy.visit('URL')
cy.wait(5000)
cy.get('.login-btn').click()
})
If you want to ignore uncaught exceptions in ALL tests you can add this to your support file. (I do NOT recommend this, I recommend fixing your application to find out why it’s throwing an exception in the first place)
// support/index.js
Cypress.on('uncaught:exception', () => false);

Related

Cypress uncaught:exception handler not working with Magic.link flow

I'm using Cypress to test a login flow that uses Magic.link auth on a mobile Web device, which is encountering the ResizeObserver loop limit exceeded error, as it tries to navigate the Google Auth forms. I've looked at numerous posts, and played around with my test, but it seems the handler is not working.
The recommended Google Authentication from the Cypress docs is insufficient, because with Magic, the flow is initiated by a call to magic.oauth.loginWithRedirect, hence I was hoping to drive the process via the UI directly.
You'll see I added a test to ensure the password input is visible. Now the exception is being thrown at that part of the test. If I remove that check the error occurs on the next step where I try to type the password.
describe('my auth flow', () => {
it('can auth with google', () => {
// click login button from my site
cy.get('button')
.contains('sign-in')
.click();
cy.origin('https://accounts.google.com', () => {
// enter email address
cy.get('input[type=email]')
.type('myuser#mydomain.com');
cy.get('button')
.find('span')
.contains('Next')
.click();
// wait for password page to show
cy.get('#password')
.should('exist')
.and('be.visible'); // error here...
// enter password
// error here if above visibility check removed
cy.get('#password input[type=password]')
.type('mypassword');
cy.get('button')
.find('span')
.contains('Next')
.click();
});
});
});
In support/commands.js, I've added the global error handler, which should handle all uncaught exceptions according to the documentation.
Cypress.on(
'uncaught:exception',
(err) => false
);
Magic does have a test mode, however I really don't want to bypass the login flow. Ideally I could exercise the login flow without hacks for testing.
The cy.origin() command is an isolated sandbox with different document and window to the primary domain.
Try adding the exception handler inside the origin command (presuming the error is happening while on the google domain).
cy.origin('https://accounts.google.com', () => {
Cypress.on('uncaught:exception', (err) => false)

Cypress auto submit on login page from beforeEach in second test

I'm working on a Cypress test for the Polish Wikipedia plugin, and I have this code in my cypress test:
Cypress.Commands.overwrite('visit', (orig, path, options) => {
return orig(`https://pl.wikipedia.org/${path}`);
});
Cypress.Commands.add('login', (pass) => {
cy.visit('/w/index.php?title=Specjalna:Zaloguj');
cy.get('#wpName1').type('<username>');
cy.get('#wpPassword1').type(pass);
cy.get('#userloginForm form').submit();
});
Cypress.Commands.add('dark_vector_wait', (pass) => {
cy.get('.vector-menu-content-list > li:nth-child(7)', { timeout: 10000 }).should('be.visible');
});
And in my spec:
describe('dark vector test', () => {
beforeEach('login', () => {
cy.login(Cypress.env('WIKI_PASSWORD'));
});
it('test discussion', () => {
cy.visit('/wiki/Dyskusja_wikipedysty:<username>');
cy.dark_vector_wait();
cy.matchImageSnapshot('discussion');
});
it('testing-page page', () => {
cy.visit('/wiki/Wikipedysta:<username>/testing-page');
cy.dark_vector_wait();
cy.matchImageSnapshot('testing-page');
});
});
And the second test is failing because as soon as Cypress type the password it automatically submits a form so cy.get('#userloginForm form').submit(); is executing after Cypress visits the home page (default redirect) and fail to find a form.
What's wrong? Why does Cypress auto-submit a form after a second time? This is not what Wikipedia is doing since the login form doesn't have any JavaScript code and you need to click login to be able to login to Wikipedia.
EDIT:
I've tried to
Use BaseURL and remove overwrite of visit.
Add type('{enter}'), but this only shows an error: cy.type() failed because this element is detached from the DOM.
EDIT 2
This is the screenshot of the action taken by cypress, second test has a page load without {enter} action and without form submit.
The problem is in Cypress.Commands.overwrite('visit').
You pass the parameter with a leading slash '/wiki/Dyskusja_wikipedysty:<username>' but concatinate to base which also has a trailing slash https://pl.wikipedia.org/${path}, so now the full path is
https://pl.wikipedia.org//wiki/Dyskusja_wikipedysty:<username>
If you set baseUrl in configuration, Cypress sorts it out for you
cypress.config.js
const { defineConfig } = require('cypress')
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
},
baseUrl: 'https://pl.wikipedia.org'
}
})
Then remove the Cypress.Commands.overwrite('visit').
With these changes, I was able to pass both tests.
Using cy.session()
The problem might be one specific to locality, I do not have any steps missing in the Cypress log.
You can try adding a session cache so that the first login is re-used.
Cypress.Commands.add('login', (pass) => {
cy.session('login', () => { // login occurs only once
// credentials are cached
cy.visit('/w/index.php?title=Specjalna:Zaloguj');
cy.get('#wpName1').type('Jack Bosko');
cy.get('#wpPassword1').type(pass);
cy.get('#userloginForm form').submit();
// for good measure, confirm login was successful
// by checking for your name on the page
cy.contains('span', 'Jack Bosko')
})
})
So the problem was the weird IME keyboard that is part of MediaWiki. I somehow got it enabled on my system even when I was not logged in. Maybe added globally with cookies or something.
I noticed that keyboard when I was asking questions on the MediaWiki support page.
This is not related to Cypress. I'm investigating why the keyboard is there, and why clean environment it.

cy.origin redirects user to a blank page

Scenario:
I am clicking a login button from my application served on localhost.
It redirects me to azure sso login through cy.origin
Authentication is performed fine.
User logs in successfully to the app.
But it redirects me to a blank page and hence rest of the IT blocks get failed.
The code attached below works fine but as soon as first IT block passes, upon the execution of second IT block page is set to about:blank so the test cases fail.
Question: What should be the workaround so that I can continue testing on application under test?
Second describe gets failed
Cypress.Commands.add('authenticate', () =>{
cy.visit('http://localhost:8080/')
cy.get('input[value="***"]').click();
cy.origin(`https://login.microsoftonline.com/`, () => {
cy.wait(3000)
cy.get('#i0116').type('username')
cy.get('#idSIButton9').click()
cy.wait(3000)
cy.get('#i0118').type('password')
cy.wait(2000)
cy.get('#idSIButton9').click()
cy.wait(2000)
cy.get('#idSIButton9').click();
})
cy.wait(6000)
cy.url().should('contain', 'Welcome')
})
According to the documentation, that behavior is by design
Take a look at cy.origin()
The cy.origin() command is currently experimental and can be enabled by setting the experimentalSessionAndOrigin flag to true in the Cypress config.
Enabling this flag does the following:
It adds the following new behaviors (that will be the default in a future major version release of Cypress) at the beginning of each test:
The page is cleared (by setting it to about:blank).
If by "Second describe gets failed" you mean the second test is not visiting the Welcome page, then just explicitly visit cy.visit('http://localhost:8080/') at the beginning of the second test.
This is the recommended approach when using cy.origin.
By the way, you should set http://localhost:8080/ as baseUrl in configuration, and use cy.visit('/') instead - from Cypress best practices.
Cypress.Commands.add("session_thing", (email, password) => {
cy.session([email, password], () => {
cy.visit('http://localhost:8080/AdminWebapp/Welcome.html')
cy.get('input[value="Log In With Office 365"]').click();
cy.origin(
`https://login.microsoftonline.com/`,
{ args: [email, password] },
([email, password]) => {
cy.wait(3000)
cy.get('#i0116').type(email)
cy.get('#idSIButton9').click()
cy.wait(3000)
cy.get('#i0118').type(password)
cy.wait(2000)
cy.get('#idSIButton9').click()
cy.wait(2000)
cy.get('#idSIButton9').click();
}
);
cy.url().should('contain', 'Welcome')
});
});
The desired behavior was achieved with above code. It restores the session in beforeEach hook. I am simply calling the cy.visit('/') in every IT block and perform the required actions which is kind of very fast with session feature.

How do I login to salesforce by using cypress?

I'm currently using cypress to do some testing. However, I have to do some tests with salesforce and it seems that I'm getting the following issue 'Whoops, there is no test to run.'
context('Salesforce', () => {
beforeEach(() => {
cy.request("https://test.salesforce.com/?un=username%40domain_name&pw=user_password&startURL=%2F001")
})
it('.click() - click on a DOM element', () => {
// load opportunity page
cy.visit('https://test.salesfroce.com/lightning/page/home')
// optional. let's the page load during the test runner
cy.wait(7000)
//cy.get('#username').type('username')
//cy.get('#password').type('password')
//cy.contains('Log In to Sandbox')
})
})
Does anyone know how to bypass the login page with cypress?
The problem that I had is that I was using a long password where extra characters didn't take into account. For this reason, I decided to change my password for something short, and now is working correctly.
This is the actual URL that you have to request and visit to make sure you can log in to your Salesforce account.
Take into consideration that cy.request is the link above & the cy.visit will be your dashboard URL.
"https://test.salesforce.com/?un=username%40domain_name&pw=user_password&startURL=%2F001

Cypress - log response data from an request after a click()

Although I know this may not be considered as a best practice, but what I want to achieve is to silently delete a record from a database after the same was created throughout UI. In htat way I want to keep our test environment clear as much as possible and reduce the noise of test data.
After my tests create a new record by clicking over the UI, I wait for POST request to finish and then I would like to extract the id from the response (so I can reuse it to silently delete that record by calling the cy.request('DELETE', '/id')).
Here's a sample test I have put on as a showcase. I'm wondering why nothing is logged in this example.
it('GET cypress and log', () => {
cy.server()
.route('**/repos/cypress-io/cypress*')
.as('getSiteInfo');
cy.visit('https://www.cypress.io/dashboard');
cy.get('img[alt="Cypress.io"]')
.click()
.wait('#getSiteInfo')
.then((response) => {
cy.log(response.body)
})
})
As far as I can see from here https://docs.cypress.io/api/commands/wait.html#Alias this should be fine.
your code contains two problems.
First:
The click triggers a new page to be loaded but cypress does not wait until the PageLoad event is raised (because you do not use visit). On my PC the Request takes about 5 seconds until it is triggered after the click. So you should use wait(..., { timeout: 10000 }).
Second:
wait() yields the XHR object, not the response. So your code within then is not correct. Also the body is passed as object. So you should use JSON.stringify() to see the result in the command log.
This code works:
describe("asda", () => {
it('GET cypress and log', () => {
cy.server()
.route('**/repos/cypress-io/cypress*')
.as('getSiteInfo');
cy.visit('https://www.cypress.io/dashboard');
cy
.get('img[alt="Cypress.io"]')
.click()
.wait('#getSiteInfo', { timeout: 20000 })
.then((xhr) => {
cy.log(JSON.stringify(xhr.response.body))
})
})
})
Instead of route and server method, try intercept directly