Handling Cypress url redirect - javascript

I have a Cypress test which clicks on an image causing a redirect to a specific url. The test then checks the url contains a specific string.
However, clicking this image causes the tests to stop/fail with a "Whoops, there is no test to run." message when the redirect happens.
The Cypress test is very simple:
/* global describe, it, cy */
import loadStory from '../../../config/cypress/helpers/loadStory'
const component = 'product-card'
const productCardImage = '[data-test=component-product-card_imageContainer]'
describe(`${component} component interaction tests`, () => {
it('clicking the image should open the products page', () => {
loadStory(component, 'Default')
cy.get(productCardImage).should('be.visible')
cy.get(productCardImage).click()
cy.url().should('contain', '/product')
})
})
My tests run on http://localhost:9002 and it seems that redirecting to http://localhost:9002/product/productId while the test suit is running is what causes Cypress to crash/fail and instead Cypress tries to go to https://localhost:9002/__/
I am wondering how I can click this image and redirect to the url without causing this crash/fail in Cypress.

Cross domain is not supported in Cypress.
Example:
step 1: You navigate to google
step 2: Search for Gmail
step 3: clicked on gmail link
You are switching from Google.com to gmail.com - cypress doesn't support this.
Workaround 1:
You can remove set href attribute value to blank as below:
target="_blank"
so that it will open in same page.
Workaround 2:
put step 1 and step 2 in one test iteration
and put step 3 in another iteration

Their is an issue of http to https.

Related

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

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.

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

Page title is showing auto-generated text instead of the real page title name using TestCafe

I have created a simple test via TestCafe which check that Google Home Page has appropriate page title. By page title here I meant title text which is located in <head><title>Google</title></head>
But when I run it locally via using t.debug() I see that page title shows random auto-generated text instead of a real page title.
Here is my test:
fixture("firstTest")
.page("https://www.google.com")
test("home page should have a title", async t => {
await t.debug()
expect(await t.title).toEqual('Google')
});
Error message is: ReferenceError: expect is not defined
Please share any ideas why this could happen.
Google page title during the test
This behavior is valid. To run tests, TestCafe uses proxy to rewrite the URL (https://testcafe.io/documentation/402631/why-testcafe#page-proxying). Getting the page title using JavaScript will return the actual value.
See the example below:
import from 'testcafe';
fixture("firstTest")
.page("https://www.google.com")
test("home page should have a title", async t => {
await t.expect(Selector("title").innerText).eql('Google')
});

Failed to launch 'URL' because the scheme does not have a registered handler

i'm trying to build a social share component with angular 11 and ionic 5. I'm using an anchor tag to call href="whatsapp://send?#text=some%20text". This works fine on devices with WhatsApp installed, but i only get the following error in the browser console on devices without WhatsApp installed:
Failed to launch 'whatsapp://send?#text=text=some%20text' because the scheme does not have a registered handler.
How can i catch this error to show the user a nice message like "Sorry, you have no WhatsApp installed"
It seems it's not possible to handle it if using href property directly.
However, if you move this logic inside your components there are several options
Inside application:
You can check the app availability using this plugin i.e.
let app;
if (this.platform.is('ios')) {
app = 'twitter://';
} else if (this.platform.is('android')) {
app = 'com.twitter.android';
}
this.appAvailability.check(app)
.then(
(yes: boolean) => console.log(app + ' is available'),
(no: boolean) => console.log(app + ' is NOT available')
);
Inside browser:
Use timeout fallback i.e.
<!-- Deep link URL for existing users with app already installed on their device -->
window.location = 'yourapp://app.com/?screen=xxxxx';
<!-- Download URL (TUNE link) for new users to download the app -->
setTimeout("window.location = 'http://hastrk.com/serve?action=click&publisher_id=1&site_id=2';", 1000);
Actually, this is the way we used in one of our web application and it worked successfully.
Use deep links handler library which allows you to work with deeplinks like this
<a href ="..." Fallback (and unsupported OSs)
data-app ="..." Deep link (cross-OS)
data-app-[os] ="..." Deep link (OS-specific)
data-store-[os]="..."> Store ID (OS-specific)
I didn't use it before so can't tell anything special regarding it
I use this to check if the app is installed or not.
"intent://scan/#Intent;scheme=whatsapp://send?#text=text=some%20text;S.browser_fallback_url=https://play.google.com/store/apps/details?id=com.whatsapp;end"

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

Categories

Resources