How to switch to the newly opened window using nodejs puppeteer? - javascript

I am having some difficulty getting puppeteer to switch its focus to the newly opened window.
The following is what my program is trying to do:
I am trying to use puppeteer to interact with Google Tag Manager preview window but I can't get it to interact with the newly opened window after clicking the submit button.
My puppeteer code is doing the following (please see screenshots below for more details):
go to https://tagassistant.google.com/#!#source=TAG_MANAGER&id=GTM-XXXXX&gtm_auth=kALKj04OP-SpPs2dMA70Tw&gtm_preview=env-562&cb=428326580326923
fill in the hostname to preview e.g. https://www.theage.com.au
click Start button
click on a menu item on the newly opened window (https://www.theage.com.au)
Puppeteer successfully perform up to step 3, however it failed at step 4 because (my first theory of the cause) its focus is still on the current window (if you do it manually on the browser, after clicking the start button, another window of the test site e.g. www.loreal.com.au will be opened).
My second theory of the cause: I also suspect it does not successfully click on the Start button because when I tried to take screenshot of puppeteer action, I can see the start button is grayed out even though the test hostname has been filled so I had to overcome that by telling it to manipulate the DOM attribute of the button to remove the "disabled" to make the button clickable. However, I'm not exactly sure if it successfully clicks through or not.
Could someone show me how to switch puppeteer focus to the newly opened window?
Thank you.
enter image description here

You haven't shown any code, so it's hard to pinpoint where the problem is. But in general, you might want to wait for popup event:
const waitForWindow = new Promise(resolve => page.on('popup', resolve));
await page.click('.my-link');
const newPage = await waitForWindow;
// now I can interact with the new page
const linksInnerTexts = await newPage.$$eval('a', links => links.map(l => l.innerText));
This is a working example if your link has target="_blank" attribute, which opens a new page in a new tab. It also works if your link looks somthing like target="popup" onclick="window.open('../html-link.htm','name','width=600,height=400'), which opens a page in a new window.

Thanks guys,
I have managed to get it working using the targetcreated event.
browser.on('targetcreated', async (target) => { //This block intercepts all new events
if (target.type() === 'page') { // if it tab/page
//const page = await target.page(); // declare it
const page = await target.page(); // declare it
const url = page.url(); // example, look at her url
console.log('***** ' + url);
//.....
}
});

Related

Selenium-webdriver, I cannot go to the modal window

I am new to automated testing. Faced such a problem, earlier in the test I go to the Iframe window to enter the "test card" data. Instead of "success page", a modal window is displayed on which I need to click. Selenium swears.
..............
await driver.switchTo().frame(driver.findElement(By.xpath('//*[#id="solid-payment-form-iframe"]'))).then.....
..............................
`await button46.click().then(async function() {
bot.sendMessage(-100********, land+"\nTest completed!!✅");
console.log(button46.click,'SubmitButton - done');
return true//it existed
})
await driver.switchTo().defaultContent();
const number = await driver.wait(
until.elementLocated(By.xpath('//*[#id="specialOffer"]/div/div[2]/div[1]/a'))
// (By.xpath('//*[#id="specialOffer"]/div/div[2]/div[1]/a'))
, 20000).then(number => {
return driver.wait(
until.elementIsEnabled(number), 20000)})await number.click();`
This is what the console writes:
ElementClickInterceptedError: element click intercepted: Element <a href="************************************* is not clickable at point (960, 536). Other element would receive the click: <iframe id="solid-payment-************************
Selenium webdriver
javascript
remote server - selenoid(aerokube)
To click an element with selenium element.click the element should be visible and clickable, but your element might be outside of the visible area or might be behind a dialog box. Try clicking by injecting javascript. I have worked with the Python version of selenium so see python code and convert according to your need:
driver.execute_script("arguments[0].click()", button46)
FIX PROBLEM:
await driver.sleep(5000)
const number1 = await driver.wait(until.elementLocated(By.xpath('//*[#id="specialOffer"]/div/div[2]/div[1]/a')))
await driver.executeScript("arguments[0].click()", number1)```

Javascript to reload a new tab page

window.open("http://google.com", '_blank');
var childWindow = "http://google.com";
childWindow.location.href = "http://google.com";
I have an eventAddListener that loads http://google.com on a new tab with a button press, but right after it opens the new tab of google.com, I want it to REFRESH again. NOT my base page but the NEW tab page, by itself. The code I showed is just one of the examples out of 5 pages worth of google search which don't work.
UPDATE:
var win = window.open('google.com', 'New Window'); setTimeout(function () { var win = window.open('google.com', 'New Window'); },3000);
This is the best i could come up with. It opens new tab and "Reloads" the new tab rather than refresh it.
What I want is for example, you click on new tab, you paste a link then press enter, which EXECUTES the link. I basically want a javascript function which EXECUTES the link.
You can't do this.
In order to trigger a reload in the new tab/window you need to run JS in that tab/window.
The same origin policy prevents this.
If you had control over the new page then you could have an event listener running in it and post a message asking that listener to trigger a refresh.
Obviously you can't do that with Google's page.
This question, however, reads like an XY problem. If the goal is to display fresh (and not old, cached, out of date) information and the target page is not a third party one then you shouldn't be using JS to hack your way around caching. Instead set better caching rules on the target page in the first place.
I worked on something similar in the past few weeks and the code below worked for me.
index.html
<button onclick="openTab()">New Tab</button>
<script>
function openTab(){
//this opens a new tab while creating a variable name for that tab
var newTab = window.open("https://google.com","_blank");
//this refreshes that new tab
newTab.location.reload();
}
</script>
Just to prove that this works on the new tab I used the code
<script>
function openTab(){
//this opens a new tab while creating a variable name for that tab
var newTab = window.open("https://google.com","_blank");
//this will alert in the new tab
newTab.alert("New Tab");
//before the following reload code takes effect
//this refreshes that new tab
newTab.location.reload();
}
</script>
Hopefully that's what you are looking for.
From my understanding you want the new tab to refresh once opened with JavaScript instead of the current tab where you run the JavaScript code from.
That's not directly possible. The JavaScript code will only run for the tab it was executed in. The newly opened tab does not know that JavaScript code should be running. The current tab cannot pass over instructions for the new tab to execute.
However, you can select the newly opened tab manually first and then execute Javascript code to refresh the page. But that probably defeats the purpose of what you're trying to do.

How to manually close print preview of a browser using JavaScript or Typescript

I have been trying many solutions but nothing helps me to solve my problem.
I have a scenario when a user trying to print a webpage from the browser menu Print option I have to redirect them to a different tab with the print version of the parent page, which I'm able to do it using the below listener.
#HostListener('window:beforeprint', ['$event'])
onBeforePrint(event) {
window.open(printUrl, '_blank');
setTimeout(() => {
const escapeEvent = new KeyboardEvent("keydown", {
'key': 'Escape'
});
document.dispatchEvent(event);
})
}
Now until navigation is fine but on my parent screen the print preview is still open and its show the default page view.
I have tried checking all possible ways of trying to close or capture the cancel button event from the print preview of the browser but no luck.
Any help will be highly appreciated.

How to click item on a new website HTML and JS

I am trying to code an auto clicker that can open a new tab on the click of an HTML button and start clicking. When clicked, JS should open a new tab and begin clicking. However, it does not seem to work. I have figured out that the JS will not run on a new tab, but I can't figure out how to fix it. Code sample below:
function updateButton() {
window.open("https://clickthatbutton.com", '_blank');
document.getElementById("submit").click();
}
Documentation says window.open returns object representing created window. So you can store it in variable and access its document:
function updateButton() {
const w = window.open("https://clickthatbutton.com", '_blank');
w.document.getElementById("submit").click();
}

Click on "onclick"-login-button using Puppeteer

I'm experiencing difficulties using Puppeteer to automate a login for a webside that uses an "onclick" script to pop-up it's login window. The login-link looks like this:
<li>
Login
<span class="blu">oder</span>
Registrieren
</li>
Unfortunately the page doesn't offer a login prompt that enables to address the login fields by its ID directly like shown in many puppeteer-examples. There is only the possibility to login using this pop-up window.
I tried many different approaches to get this login prompt opened up like:
(await page.$$eval(selector, a => a.filter(a => a.textContent === 'Login')))[0].click();
or
let selector = 'a';
page.$$eval(selector, anchors => {
anchors.map(anchor => {
if(anchor.textContent == 'Login') {
anchor.click();
return
}
})
});
After these actions I expect to see this login window in the screenshot I do right after this using
await page.screenshot({ path: screenshot2 });
I also tried to use its x-path using page.$x(). Unfortunately none of these worked. The screenshot that I took right after the action returned the same result of the page like right before the intended click. I expect to see the login window popped up on the screenshot. Might it be that the screenshot function doesn't show this window even though it would be visible?
Is there a way to see the browser in action while a puppeteer script is executed? I did some experiments using
const browser = await puppeteer.launch({ headless:false });
But this didn't show any browser window. So currently I only have the screenshots as a return value.
Unfortunately I'm not too familiar with JavaScript...
How can I achieve to get this link clicked?
I found a better way: Selenium + python. Works right away. Awesome debugging functionalities. Supports Firefox as well. Easier syntax. Less Brainfuck.

Categories