Reputation: 6781
The question is as simple as that. In Cypress, how can I access a new window that opens up when running the test.
Steps to recreate :
- Run the test. After some action, new window pops up (the url is dynamic in nature).
- Fill in the fields in the new window, and click a few buttons.
- After required actions are completed in the new Window, close the new window and move back to the main window.
- Continue execution with the main window.
Point of interest: the focus should be
main window -> new window -> main window
I have read few things that relate to use of iframe
and confirmation box
, but here its none of those. Relates to accessing a whole new window. Something like Window Handlers
in Selenium. Unfortunately could not find anything related to it.
Upvotes: 72
Views: 104797
Reputation: 51
Below is my solution, hope this helps you:
let openUrl
cy.window()
.then((win) => {
cy.stub(win, 'open').callsFake((url) => {
openUrl = url
return win.open(url)
})
})
.as('openWindow')
// trigger window.open()...
cy.get('@openWindow').then(() => {
cy.visit('http://example.com/' + openUrl)
})
Upvotes: -1
Reputation: 1
what helped me:
get myButton() { return cy.get('a') }
cy.window().then((win) => {
cy.stub(win, 'open').as('redirect').callsFake(url => {
cy.visit(url);
});
myButton.invoke('removeAttr', 'target')
});
myButton.click();
Upvotes: 0
Reputation: 194
I was able to achieve the same requirement via the following:
let newUrl = '';
cy.window().then((win) => {
cy.stub(win, 'open').as('windowOpen').callsFake(url => {
newUrl = url;
});
})
cy.get('.open-window-btn').click()
cy.get('@windowOpen').should('be.called');
cy.visit(newUrl)
Upvotes: 12
Reputation: 19
this is how you can handle tabs in same window..
use this code snippet
cy.xpath("//a[@href='http://www.selenium.dev']").invoke('removeAttr','target').click();
Upvotes: 1
Reputation: 306
I was recently faced with this issue as well - url for the new tab is dynamic, so I don't know what it is. After much searching, some trial and error, and input from co-workers, resolved by doing the following:
// AFTER cy.visit()
cy.window().then((win) => {
cy.spy(win, 'open').as('windowOpen'); // 'spy' vs 'stub' lets the new tab still open if you are visually watching it
});
// perform action here [for me it was a button being clicked that eventually ended in a window.open]
// verify the window opened
// verify the first parameter is a string (this is the dynamic url) and the second is _blank (opens a new window)
cy.get('@windowOpen').should('be.calledWith', Cypress.sinon.match.string, '_blank');
Upvotes: 7
Reputation: 6905
Accessing new windows via Cypress is intentionally not supported.
However, there are many ways this functionality can be tested in Cypress now. You can split up your tests into separate pieces and still have confidence that your application is covered.
- Write a test to check that when performing the action in your app, the
window.open
event is called by usingcy.spy()
to listen for awindow.open
event.
cy.visit('http://localhost:3000', {
onBeforeLoad(win) {
cy.stub(win, 'open')
}
})
// Do the action in your app like cy.get('.open-window-btn').click()
cy.window().its('open').should('be.called')
- In a new test, use
cy.visit()
to go to the url that would have opened in the new window, fill in the fields and click the buttons like you would in a Cypress test.
cy.visit('http://localhost:3000/new-window')
// Do the actions you want to test in the new window
Fully working test example can be found here.
Upvotes: 94
Reputation: 357
Here's a solution i'm using on my project based on "Cypress using child window"
Cypress Window Helpers (aka. Cypress Tab Helpers) They're really popup-windows or child-windows, but i call them tabs for api brevity
cy.openTab(url, opts)
cy.tabVisit(url, window_name)
cy.switchToTab(tab_name)
cy.closeTab(index_or_name) - pass nothing to close active tab
cy.closeAllTabs() - except main root window
Upvotes: 6
Reputation: 5844
// We can remove the offending attribute - target='_blank'
// that would normally open content in a new tab.
cy.get('#users').invoke('removeAttr', 'target').click()
// after clicking the <a> we are now navigated to the
// new page and we can assert that the url is correct
cy.url().should('include', 'users.html')
Cypress - tab handling anchor links
Upvotes: 12
Reputation: 1118
I am not cypress expert, just started using it few days ago, but I figured out this kind solution for stateful application with dynamic link:
// Get window object
cy.window().then((win) => {
// Replace window.open(url, target)-function with our own arrow function
cy.stub(win, 'open', url =>
{
// change window location to be same as the popup url
win.location.href = Cypress.config().baseUrl + url;
}).as("popup") // alias it with popup, so we can wait refer it with @popup
})
// Click button which triggers javascript's window.open() call
cy.get("#buttonWhichOpensPopupWithDynamicUrl").click()
// Make sure that it triggered window.open function call
cy.get("@popup").should("be.called")
// Now we can continue integration testing for the new "popup tab" inside the same tab
Is there any better way to do this?
Upvotes: 26