Get list of Chrome Windows (OS-Level) - webdriver-io

I thought initially that I could retrieve Chrome Windows by using:
browser.getWindowHandles()
Problem with that is that it doesn't actually get Chrome "Window" but Tabs. Is there anyway in Selenium to have a concept of real "visual" Chrome window? I want to know if a Tab is from a specific Window and how many tabs in a Window specifically. The doc is misleading especially with getAllWindowHandles which implies that it's about Window.
I'm basically looking for a solution to get "OS Window" and their tabs. I've switched from Selenium to WebdriverIO maybe thinking it's possible but I can't find in the docs.
Thanks guys for the help!

https://stackoverflow.com/a/34655248/6793637
Windows and Tabs are similar , it depends on the browser setting whether the new link should be open in a tab or window.
if you open a new window or tab both will be detected in selenium/wdio . Note that the tab or window count is for the window that was opened by the selenium session and not the entire windows opened in your system
eg
it('should login with valid credentials', async () => {
await LoginPage.open();
// opens new tab
await browser.execute((a) => { window.open(a) }, 'http://the-internet.herokuapp.com/login')
await expect((await browser.getWindowHandles()).length).toBe(2);
//opens new window
await browser.execute((a) => { window.open(a, 'target', 'features') }, 'http://the-internet.herokuapp.com/login')
await expect((await browser.getWindowHandles()).length).toBe(3);
await browser.pause(5000);
});

Related

How to enter Immersive Reader on Microsoft Edge through Selenium?

On a high level, does anyone know how to enter the Immersive Reader mode on Microsoft Edge when it is available for a given webpage through Selenium?
My aim is to load up a page, enter Immersive Reader, and save the page's source code to disk. I'm firing up Edge through Docker and I'm pragmatically connecting to it via a Node.js script.
I've tried driver.actions().sendKeys(KEY.F9), but that doesn't work since I'm targeting the browser and not a DOM element.
Many thanks for all your help.
New
Just run
driver.get('read://' + url)
and the site is loaded in immersive reader mode if available.
Old
To interact with the UI you have to use pyautogui (pip install pyautogui) and then run this code while the browser window is on focus/active:
import pyautogui
pyautogui.press('F9')
It is also useful for example to save a pdf by interacting with the popup window appearing when pressing CTRL+S.
Here's a bit of code for anyone else who might stumble across this:
Credits to #sound wave for helping me get there!
const { Builder } = require('selenium-webdriver');
const fs = require('fs');
(async () => {
const driver = await new Builder().forBrowser('MicrosoftEdge').usingServer('http://localhost:4444').build();
await driver.get('read://https://www.bbc.co.uk/news/entertainment-arts-64302120'); // this URL needs to be Immersive Reader supported
await driver.switchTo().frame(0);
const pagesource = await driver.getPageSource();
fs.writeFile('test.html', pagesource, err => {
if (err) {
console.log(err);
}
});
const title = (await driver.getTitle()).trim();
console.log(title);
await driver.quit();
})().catch((e) => console.error(e));

Wait for page to load after click() on download button

It is possible to somehow skip waiting for page to load, after Cypress test click() on download button which start download but does not redirect to other page?
it('name of the test', () =>{
cy.get('#btnGeneratePdf').click()
.url().should('contain', "/Closed"); //url is same as before than button for download was clicked
})
This is a known Cypress problem. A lot of related issues have been opened on Cypress github, however you can follow the main discussion in this one.
Right now you cannot skip the Cypress waiting for load after clicking the anchor, but there is a workaround - you can force your page to reload after the file has been downloaded, to make the test not fail. There is a 5 seconds timeout that you can adjust to make sure the file gets to download before the page reloads.
cy.window().document().then(function (doc) {
doc.addEventListener('click', () => {
// this adds a listener that reloads your page
// after 5 seconds from clicking the download button
setTimeout(function () { doc.location.reload() }, 5000)
})
cy.get('#btnGeneratePdf').click()
})
This issue has been around for a long time. Hopefully Cypress team will resolve it soon.

How do I deal with a page loading in a secondary browser tab when I run Protractor tests headless (Chrome)?

When this code clicks a “Print”-icon, a PDF-file will be generated and displayed in a new browser-tab. I want to switch to this tab, wait until the PDF has finished loading there, check a part of the URL and then close that secondary tab.
it( "should open document as PDF-file in new browser-tab", async () => {
const mUrl = "TherapyReportForm/Export";
await mTherapyReportView.btnPrintform.click();
await browser.getAllWindowHandles().then(async (handles) => {
//if there is a secondary browser-tab open...
if (handles.length > 1) {
//...click on it
await browser.driver.switchTo().window(handles[1]);
}
});
//confirm that the url of the secondary tab matches the print-url pattern
await browser.sleep( 18000 );
expect( await browser.getCurrentUrl() ).toContain( mUrl );
await browser.getAllWindowHandles().then( async (handles) => {
//if there are multiple browser-tabs open
if (handles.length > 1) {
//close the secondary and move back to first
await browser.driver.close();
await browser.driver.switchTo().window( handles[0] );
}
} );
} );
The test above works reliably, unless I run it in chromes headless-mode, then the test-run breaks at line
expect(await browser.getCurrentUrl()).toContain(mUrl);
console output
The console output proves that it switches to the secondary tab, but apparently never tries to load the url. Since it fails to close this secondary tab the entire suite will break at that point.
What am I doing wrong?
Here is a thing... downloading functionality is not available in headless chrome. That's for sure. What I'm going to talk about below, I'm a little bit uncertain if that's the case
There is no such thing as 'open' pdf file in browser. The reason is that behind scene the browser actually downloads it (maybe temporarily). This is why you'll never be able to do that in headless
But that's rather a shot in the dark

TestCafe: Testing a Page Opening a PDF in a New Tab

Part of the web application I am testing is to click a button, which normally opens a PDF in a new tab. This enables the user to go forward in the application. The PDF can be ignored.
Currently, my strategy is to click the button and then navigate back using ClientFunction. TestCafe successfully opens the PDF when the button is clicked, but it is opened in the same tab and the test is then stuck. Navigating back changes the URL, but the PDF is still displayed.
const goBack = ClientFunction(() => window.history.back())
await this.t.click(this.button)
await this.t.wait(10000)
await goBack()
Is TestCafe currently able to bypass this issue, as I don't need to actually do anything with the PDF?
TestCafe allows testing html pages, but not PDF files. So, you can check the generated link to the PDF file as a string without actually following this link. For example:
const overrideWindowOpen = ClientFunction(() => {
window.open = function (url) {
window.__lastWindowOpenUrl = url;
};
});
const getResultUrl = ClientFunction(() => window.__lastWindowOpenUrl);
await overrideWindowOpen();
await t
.click(this.button)
.expect(getResultUrl()).eql('http://example.com/path/to/PDF/93023813-0984-1');
See also: Multiple Browser Windows

How to close the safari pop up dialogue when running automate script with nightwatch on BrowserStack?

I use Browserstack to do the E2E testing, now I met a problem when I try to run the mobile automate script in safari on Browserstack, there will have a pop-up dialogue show when I click a button which will result in opening a new tab, the dialogue show message like this: 'this site is attempting to open a popup window', I must close it and the script can continue executing.
Now the problem is:
1. When I click the button which will trigger this pop-up dialogue, there will always show an exception in the log: 'Error while running .clickElement() protocol action: Appium error: An unknown server-side error occurred while processing the command. Original error: Did not get any response after 20s'.
2. I can use the XPath to locate the button on the pop-up dialogue and click it to close the dialogue, but it takes serval minutes, is there another way to do this operation more efficient?
const { client } = require('nightwatch-api')
const { Given, Then, When} = require('cucumber')
Given('open mobile 163 news', async function () {
await client.url('https://3g.163.com/news/article/EJN99AOF000189FH.html?clickfrom=index2018_news_newslist#offset=0')
})
When('choose share by QQ', async function () {
await client.waitForElementVisible('.sharelogo')
await client.click('.sharelogo')
})
Then('the popup should show', async function () {
await client.waitForElementVisible('.qzone')
await client.click('.qzone')
await client.setContext('NATIVE_APP')
await client.source(function(res){
console.log(res.value)
})
await client.useXpath()
await client.click('//*[#name="Allow"]')
await client.contexts(function(result) {
client.setContext(result.value[result.value.length - 1])
client.useCss()
})
})
Have you tried adding the capability 'nativeWebTap' and setting it to the value 'true' in the test scripts?