How to handle a windows prompt in a test automation using Cypress? - javascript

I am new to using Cypress for web automation. I am still scouring through the internet looking for answers to this but I cannot find a solution that works for me.
This is what I'm trying to do in my test:
User clicks a link.
A new tab is opened and a windows prompt appears, requesting user input (username, password). (Since Cypress doesn't allow opening new tabs, I've removed the target attribute.)
Upon logging in successfully, the page has a download button.
User clicks on the download button.
The first struggle - I could not enter values into the windows prompt. In the below code, I was trying to see if the 'Sign In' button on the windows prompt would be clicked, but it was not.
cy.window().then(win => {
cy.get('#documentPassword').then((finalPassword) => {
const stub =cy.stub(win, 'prompt')
stub.returns('test')
cy.get('button#signin').click()
})
})
I got an Assertion Error: Timed out retrying after 25000ms: Expected to find element: button#signin, but never found it.
After no luck with this, I moved on to another suggestion.
The second struggle - I tried putting the username and password into the link, like this: https://username:password#mytestingwebsite.com. Just to note, when I paste the link manually into a browser, it works. To test this out, this what I had done:
cy.visit('https://mailtrap.io')
// ...other steps
cy.forceVisit('https://username:password#mytestingwebsite.com')
I added a custom command forceVisit to the commands.js file:
Cypress.Commands.add('forceVisit', url => {
cy.window().then(win => {
return win.open(url, '_self');
});
});
The result is the second url does not load.
Hoping for any insight from you guys. Thanks in advance.

This works for me:
cy.visit('https://mytestingwebsite.com', {
auth: {
username: 'username',
password: 'password'
}
})
This didn't work for me the first time I tried it because I still passed the credentials in the url.

Related

Why does my web page keep crashing at the end of this test?

I am using Cypress to run a test, I sent one email to the other then sign into the second email to see if the email was sent. Unfortunately though at the bottom of the below code the webpage in Cypress turns to blank. Any idea why and what I can do to fix it?
it('Send email', function () {
cy.visit('https://login.yahoo.com/?.src=ym&pspid=159600001&activity=mail-direct&.lang=en-GB&.intl=uk&.done=https%3A%2F%2Fuk.mail.yahoo.com%2Fd');
cy.get('.phone-no').type('//password here{enter}');
cy.get('.password').type('//password here{enter}');
Cypress.on('uncaught:exception', (err, runnable) => {
return false
})
cy.get('.e_dRA').eq(0).click();
Cypress.Commands.add('typeTab', (shiftKey, ctrlKey) => {
cy.focused().trigger('keydown', {
keyCode: 9,
which: 9,
shiftKey: shiftKey,
ctrlKey: ctrlKey
})
})
cy.get('.select-input').eq(1).type('//email here');
cy.get('[role="textbox"]').type('Hi Second Email, the weather will be 10oc plus in the following destinations - Regards, First Email');
cy.get('[title="Send this email"]').click();
cy.get('[data-test-id="primary-btn"]').click();
cy.get('._yb_1golm').click();
cy.get('[data-soa="Sign out of all"]').click();
cy.get('[data-redirect-params="pspid=[[pspid]]&activity=ybar-signin"]').click();
cy.get('.pure-button').eq(1).click();
//Crashes here
});```
Cypress has some limitations with social login as mentioned here git issue
If the requirement is to handle emails there are few alternatives like mailosaur which can help you. Also there is a npm plugin - cypress-social-logins which provides social login capabilities for some providers
I have dealt a lot with webpages crashing when running Cypress tests. I do not know the specifics of your application, BUT I can give you some pointers. This entire block of code should have cy.wait(int) before fragile steps. I suspect that your application is crashing because Cypress is moving too fast. FYI cy.wait() is in milliseconds.
Here are some examples:
cy.get('.select-input').eq(1).type('//email here');
cy.get('[role="textbox"]').type('Hi Second Email, the weather will be 10oc plus in the following destinations - Regards, First Email');
cy.get('[title="Send this email"]').click();
cy.get('[data-test-id="primary-btn"]').click();
cy.get('._yb_1golm').click();
cy.wait(300)
cy.get('[data-soa="Sign out of all"]').click();
cy.wait(300)
cy.get('[data-redirect-params="pspid=[[pspid]]&activity=ybar-signin"]').click();
cy.wait(300)
cy.get('.pure-button').eq(1).click();
You can adjust these to different values. Let me know how it goes!

Not allowed to launch cutom protocol because a user gesture is required

I need to run my custom protocol twice but it doesn't work the second time, I got this error ( Not allowed to launch 'cutomProtocol' because user gesture is required. ) I tried to find a solution but I did not find any!
Same problem with chrome, firefox and edge.
I need to see this popup twice
window.location.href = 'my-protocol://${base64}';
and
customProtocolVerify(
`my-protocol://${base64}`,
() => {
// successCb: Callback function which gets called when custom protocol is found.
console.log('My protocol found and opened the file successfully..');
},
() => {
// failCb: Callback function which gets called when custom protocol not found.
console.log('My protocol not found.');
}
);
I tried with these two and didn't work
Clarification
I have a custom protocol.
My scenario:
check if it's installed successfully (I'm using customProtocolVerify method) and that method makes the launch if the protocol is found
run some APIs
launch the protocol again
My problem:
Step 3 doesn't work, I have the error on the console that says " Not allowed to launch... " and of course I can't see my popup to open my protocol.
I'm asking for help to make step 3 work
The only way to bypass this "bug" is to ask the user twice (or in a loop) by showing a OK alert or some sort of user confirm box.
My solution:
OpenLinkInExternalApp(Link);
alerty.alert('', { title: '', okLabel: 'Open Link' }, function () {
OpenLinkInExternalApp(Link);
});
The above code will open the external app, then a OK alert will pop up, after clicking OK, I call the same code again. Do this in a loop if needed.
TIP:
We guide our users to use split screen at this stage. This is where users can dock your web-app on the left and the external app on the right as an example.
Alert Box:
We user Alerty.js https://github.com/undead25/alerty#readme

Cypress changes the URL and it breaks the app

I'm learning Cypress and for that purpose I am using this site: automationpractice.com.
Scenario: Sign up. In the sign up form the app validate the email (1) then it is redirected to another form (2).
In this flow, Cypress throws the following error:
CypressError: Cypress detected a cross origin error happened on page load:
> Blocked a frame with origin "http://automationpractice.com" from accessing a cross-origin frame.
Before the page load, you were bound to the origin policy:
> http://automationpractice.com
A cross origin error happens when your application navigates to a new URL which does not match the origin policy above.
I don't know why of this error, the form 2 is not inside an iframe, is the same url. Anyone knows?
Trying to fix it, "chromeWebSecurity": false was added to cypress.json. Then, after "Register an Account" button is clicked the second form is loaded inside cypress viewport but cypress changes the url to http://automationpractice.com/__/#account-creation, so the form disappears and the fields are not located.
I suppose that avoiding that cypress change the url I can solve this issue. But, I couldn't find any related in the documentation. Anyone knows how to solve it?
// test.spec.js
context('Cypress Training', () => {
beforeEach(() => {
cy.visit('http://automationpractice.com/index.php?controller=authentication&back=my-account')
})
it('Register user', () => {
const email = 'test#test.test.test';
// form 1
cy.get('#email_create').type(email)
cy.get('#SubmitCreate').click();
// form 2
cy.wait(3000)
cy.get('#id_gender1').click()
})
})
The solution is here: https://github.com/cypress-io/cypress/issues/7402
You have to upgrade cypress to version 4.6.0 and add
{
"experimentalSourceRewriting": true
}
to cypress.json

Facebook SDK change display type in the FB.login()

I'm working on the Facebook Login integration into my website and I've done everything which was necessary to achieve this and described in the Facebook documentation
So I'm using FB.login() method
export function facebookLogin() {
return new Promise((res: any, rej: any) => {
// TODO: maybe it might be moved to some dedicated API file? But we don't want to use it anywhere else
FB.login((response: FacebookLoginCallbackResponse) => {
if (response.authResponse) {
res(response.authResponse);
} else {
rej();
}
}, {scope: "public_profile, email"});
});
}
It works fine but when the popup is opened (and it's really big. I would like to make it smaller) the warning shows at the bottom of window.
You are using a display type of 'page' in a small browser window or popup. For a better user experience, show this dialog with our JavaScript SDK without specifying an explicit display type. The SDK will choose the best display type for each environment
The question is: How to change it? There is no option TYPE in the Login Dialog parameters. I didn't found anything about this possibility in the Login Dialog documentation.
Can someone give me some tip, please?

Accessibility Testing using Pa11y 5 on a page with Popup / Overlay

I have a page that I'm able to get accessibility test report from Pa11y 5 using actions.
When I click on a button on that specific page, I get a popup/overlay, I would like Pa11y to sniff that popup/overlay page and report on accessibility metrics, but currently Pa11y 5 is only able to provide me for the main parent page ignoring any reports on the html in the popup page? Is there a way to achieve this, tell Pa11y to switch to popup and sniff on that popup html and report that.
Popup/overlay contains div[role='dialog'] as it is a modal dialog made out of aria.
I'm using the latest Pa11y, hence I keep mentioning it as Pa11y 5. I have not used Pa11y4, so cannot comment if this works with Pa11y 4.
Any help/advise is sincerely appreciated.
Update:
As requested, below is my complete (relevant) part of the code
const PageOptions1 = {
timeout: 30000,
userAgent: 'A11Y TESTS',
actions: [
'screen capture screenshots/001-DefaultView.png'
]
};
const PageOptions2 = {
timeout: 35000,
userAgent: 'A11Y TESTS',
rootElement: 'div[role="dialog"]',
actions: [
'click element button[data-automation-id="ccbutton"]',
'wait for element div[role="dialog"] to be added',
'screen capture screenshots/002-Popup.png',
'click element i.fa-close',
'screen capture screenshots/002-DefaultView.png'
]
};
async function runPa11y(navigateUrl) {
try {
const results = await Promise.all([
pa11y(navigateUrl, PageOptions1),
pa11y(navigateUrl, PageOptions2),
]);
LogResults(results);
} catch (error) {
console.error("Error: " + error.message);
}
}
runPa11y("Url to navigate");
Thanks for your updates! You're doing the right things and everything looks like it's working as expected.
Pa11y will perform all of the Actions before running your test, so it's opening the modal dialog, immediately closing it again, and then running the test without it.
Break PageOptions2 into smaller units so that your last Action is the state you want to test against, and everything should be ok.

Categories

Resources