Powershell Website Automation: Javascript Popup Box Freeze - javascript

I am trying to automate a process in which the user downloads a file extract from a website. My issue is that once the 'export' button in clicked, a javascript popup window comes up with various date parameters for the extract along with the final 'DOWNLOAD' button that needs to be clicked. The problem arises during this javascript popup window. Once the export button is clicked and the popup window opens, powershell seems to freeze up during the script and will not allow any further commands to be executed.
I have tried using the WASP module along with SELECT-WINDOW in order to grab the correct IE process window, however the 'Select-Window -Title "NAME OF POPUP WINDOW - Windows Internet Explorer" | Select -First 1 | Set-WindowActive' command will not execute as Powershell gets stuck 'Running script' immediately after the initial 'export' button is clicked (right when the popup window opens). Is there a way I can either 'refresh' Powershell after the popup box is opened in order to execute further commands, or any ideas on a way to break out of the continuous 'Running script' loop that I get stuck in with this Javascrip popup window?
# Set access URL and Credentials
$WebU='username'
$WebP='password'
$URLlogin='http://websiteurl.com'
$IEwait="1000"
# Execute IE and navigate to URL
$ie = New-Object -com "InternetExplorer.application";
$ie.visible = $True;
$ie.navigate($URLlogin);
Try{
# Login steps
while ($ie.Busy ) { Start-Sleep -Milliseconds $IEwait; }
if ($ie.Document.getElementByID("txtLogin"))
{ $ie.Document.getElementByID("txtLogin").value = $WebU }
while ($ie.Busy ) { Start-Sleep -Milliseconds $IEwait; }
if ($ie.Document.getElementByID("txtPassword"))
{ $ie.Document.getElementByID("txtPassword").value = $WebP }
while ($ie.Busy ) { Start-Sleep -Milliseconds $IEwait; }
if ($ie.Document.getElementByID("btnLogin"))
{ $ie.Document.getElementByID("btnLogin").Click() }
# Navigate through website to find the 'Export' button
while ($ie.Busy ) { Start-Sleep -Milliseconds $IEwait; }
if ($ie.Document.getElementByID("managementMenu_btnLearningResults"))
{ $ie.Document.getElementByID("managementMenu_btnLearningResults").Click() }
while ($ie.Busy ) { Start-Sleep -Milliseconds $IEwait; }
# This is the part that freezes the script. Once the 'btnExport' button is clicked, a JS popup keeps Powershell from executing any additional commands
if ($ie.Document.getElementByID("btnExport"))
{ $ie.Document.getElementByID("btnExport").Click() }
# Once the popoup box opens, sending the 'ENTER' key should automatically download the export file
Select-Window -Title "NAME OF POPUP WINDOW - Windows Internet Explorer" | Select -First 1 | Set-WindowActive
Select-Window -Title "NAME OF POPUP WINDOW - Windows Internet Explorer" | Select-childwindow | Send-Keys "{ENTER}"
}
# These won't execute because the JS popup window confuses Powershell and keeps it in a continuous 'Running Script' process
Catch {
"Error" }
Finally {
"Now able to execute further commands" }

This problem comes up a lot when automating GUI browsers - modal dialogs like the JS popup you describe will block your script from finishing until someone dismisses it. This is because the call you made into browser itself (which caused the modal dialog to appear) is also blocking, waiting for interaction from the user.
In my experience the easiest way to deal with this scenario is to launch a separate process just to handle the modal dialog. It takes two steps:
Write a small standalone script/program that will wait for the modal dialog to appear, then dismiss it. This is easy to test by launching the popup-handling script manually, then manually performing the steps that make the dialog appear.
Once you have that working, in your main program that automates the browser, launch your separate dialog-handling script just before you execute the line of code that creates the modal dialog.
And that's it. It feels clunky but it will work in pretty much any case I've seen (unless the modal dialog requires elevated security privileges, which brings up other issues).
Also, if you're using a programming language that has native thread support, you can launch a separate thread (instead of a process) to handle modal dialogs.
Some test automators feel it's actually cheaper (in terms of script development and maintenance time) to simply bypass modal dialogs like this if possible, assuming you can get around it and still feel confident in your testing. Sometimes this might require modifying the application to give your test code a special interface into the system.

The IE object model is actually kind of treacherous. It often says things are ready when they aren't, because an underlying resource hasn't yet loaded. I got annoyed rewriting this code each time I had to interact with a page, so I wrote a module called AutoBrowse to deal with it:
http://autobrowse.start-automating.com/
Use this instead, and you will sidestep the issue.
Hope this helps

While ( $ie.busy -eq $true){
[System.Threading.Thread]::Sleep(2000);
$wshell = New-Object -ComObject wscript.shell;
if($wshell.AppActivate('Message from webpage'))
{
[System.Threading.Thread]::Sleep(1000);
[System.Windows.Forms.SendKeys]::SendWait('{Enter}')
}
}

Related

How to debug a tab in Google Chrome that freezes right from the browser start?

In a vue web application, I have the issue that I have some deep links (example.com/app/some/123) that are handled by the application (vue-router).
Sometimes (not always), for whatever reason when clicking such a link (in Outlook or from a desktop shortcut) when no browser window is opened, Chrome starts but immediately freezes (tab becomes unresponsive).
It feels like there is some redirect loop going on in my application code that causes this freeze. But my issue is that I have no clue on how to debug this to find the spot:
Opening the devtools is possible using the menu but JS files/code does not "load" - Scripts tab stays empty
Clicking the pause button does nothing, the same applies to pressing F8 (pause script execution)
The profiler cannot start (stays at "initializing").
I also have the feeling that this happens when a new version of the app (js bundle) is published but Chrome has some previous version cached. It feels this more often produces the issue. But this is just a guess.
Clicking the pause button/F8 is my regular procedure to tackle such things to find the spot where we are in the JS code at the moment. But unfortunately, here, this does not work as most of the browser is unresponsive.
The only way to close Chrome is to kill it via the task manager.
Is there any way to enable additional logging via Chrome settings or activate an "immediate debug session" right when the browser process starts to somehow get closer to the JS code that freezes the whole tab?
So ideally that somehow, right from the browser start, a profile of the "debug session" is saved even if the browser is process-killed that can later be inspected?
You could try webQsee (https://chrome.google.com/webstore/detail/webqsee-web-sniffer-recor/gamdpfnfkjknkimfbboonmgdfnondfme). The extension provides some usefull export features that might help you identifying the root cause.
Event Snapshot
Exports Screenshot, Cookies, Network and Console output. A lot of info but it is a proprietary format, in can only be analysed in the extension itself.
Excel Export
Like an HAR export, but also including Console output.
These two export options (and more) are available via the export menu located at the bottom of the extension window.

Bypass "user gesture" requirement when testing "beforeunload" dialogue in Cypress

I am trying to write a Cypress test to validate that a beforeunload dialogue appears when a user tries to navigate away from an incomplete form.
When a user tries to leave a page after interacting with a form, my site activates a beforeunload dialogue to warn them unsaved data may be lost. Everything works fine when I test the behavior manually but When I try to write a test in Cypress I get
'[Intervention] Blocked attempt to show a 'beforeunload' confirmation panel for a frame that never had a user gesture since its load. https://www.chromestatus.com/feature/5082396709879808'.
This is after typing in various fields and simulating click() events. It seams that JS does not trigger a true "user gesture" . I understand why Chrome does this but I would hope there would still be a way to write tests. I've found workarounds for a similar problem with video playback # https://github.com/cypress-io/cypress/issues/2376. But this does not seam to work for "beforeunload". None of the flags I found here seam to work https://peter.sh/experiments/chromium-command-line-switches/
on('before:browser:launch', (browser = {}, args) => {
if (browser.name === 'chrome') {
// Mac/Linux
args.push('--disable-gesture-requirement-for-presentation')
}
return args
})
Hoping there might be a work around. Can I either simulate an actual "gesture" in Cypress or disable the requirement in Chrome? Any help is greatly appreciated.

How do I close a tab in Eclipse using Javascript?

I am currently modernising some plugin modules from version 2.x to the OSGi-based 4.x. This project uses the Eclipse application and takes advantage of its view & perspective architecture to serve as a tabbed browser.
Studying the old code and running the Eclipse application, this is what I understand to be the expected behaviour of one particular functionality:
Clicking a link opens a panel in a new tab, which displays a HTML file containing Javascript in it.
The HTML page contains a form culminating in a Submit & Cancel button.
Clicking either button should close the tab. The submit button will, of course, first submit the form data.
Most of the above works as intended, however instead of closing just that one tab, clicking either button causes the entire Eclipse application to attempt to terminate (I received a confirmation prompt asking if I want to exit Eclipse). The submit button did successfully update submitted info into the database before attempting to terminate the Eclipse application.
This is what the offending part of the code looks like:
function onSubmit() {
//processForm();
if (opener) {
opener.newAddressValue(newToAddress);
window.close();
} else if (parent.parent) {
parent.parent.newAddressValue(newToAddress);
parent.parent.closeUsrFrame();
} else {
parent.newAddressValue(newToAddress);
parent.closeUsrFrame();
}
}
function onCancel() {
if (opener) {
window.close();
} else {
parent.closeUsrFrame();
}
}
I suspect the expected behaviour is for program flow to reach window.close() at which point the tab containing the opened panel should close, but instead it is causing the entire Eclipse application to terminate. What is the correct way to exit the current tab in Eclipse 4.x using JavaScript?
If the program display a HTML file using SWT Browser widget, you can use Browser.addCloseWindowListener(CloseWindowListener listener) to hook the event that triggered by javascript window.close.
If your program do prompt about exiting Eclipse, you shall search class that implement CloseWindowListener interface. Modify its behavior as you wished.

Button "Click" issue with Rails/Capybara/Webkit (tests pass in Selenium)

I'm working on a Rails App and we've started using capybara for our functional tests. Our tech lead has had us writing tests and using Selenium, but then wants to switch to webkit for final testing prior to a deploy.
I've written a set of functional tests that mimic a user clicking through a tree menu, clicking a button to open a modal, clicking a few buttons within the modal (eventually opening a form), and then submitting the button.
These tests pass with flying colors in selenium. Firefox pops open and it whips through the complete test suite.
Switch over to webkit, and there is a consistent point at which the tests fail. When the modal is open, and it attempts to "click" a button to switch from a "Interaction History Form" to a "New Interaction Form"
The following is a list of the various command attempts I've done at "clicking" the New Interaction Button.
With selenium, this is simple and works:
click_button('New Interaction')
and some of these work in selenium, some don't, but none of them work with WebKit.
# page.execute_script %Q{ $('.btn.btn-default.toggle-interaction').css('display, inline-block'); }
# page.execute_script %Q{ $('.fa.fa-plus').click(); }
# page.find('.btn.btn-default.toggle-interaction').click
# within('#interaction-history') { find_button('New Interaction').click }
click_button('New Interaction')
# find_button('New Interaction').trigger('click')
# within(".btn.toggle-interaction") do
# click_on("New Interaction")
# end
# find('.btn.toggle-interaction').trigger('click')
# find_button('New Interaction').click
# within('.insight-wrapper') { find_button('New Interaction').click }
We decided to try and use the capybara-screenshot gem, so that we could get a snapshot of the HTML and the "rendered" page during headless test failure.
I don't have a good photo editing app so I can't scrub out the protected info to post a screenshot, but in the saved snapshots (and saved html files), the images look right.
One idiosyncrasy in the screenshots is the location of the mouse cursor in the screenshot. Sometimes it's on the button it attempted to click, and other's it isn't.
One other idea we entertained is the idea that it could be a timing issue, and that it's trying to click the button before it has been successfully rendered. To mitigate that we added a pause method that forced the tests to wait. That didn't resolve the issue.
We looked at switching to a headless selenium using poltergeist/phantomJS, but a lot of the comments on that route seem to indicate a higher quantity of "random JS errors" than with webkit. Would there be an alternative headless selenium solution that could be worth investigating?
Thank you for your time and help,
Alex

Selenium IDE automation seems to break JavaScript window

I'm using selenium IDE (currently available only on firefox) to do some automated testing of a site I'm coding. When selenium navigates to, a form filling page, and fills in the info - a 'window.alert()' is called by a button.
When using selenium my set of commands look like this:
open /
clickAndWait document.form1.Action[1]
select stuff
type stuff
etc, etc
click name=myPreview
When I click through recording this the first time, it works no problem. When I rerun the script window.alert and alert don't work from the console or anything. I've debugged it, and its not working.
When a window.alert() is called as part of a selenium script (I'm talking at least in the IDE), it is called even though a user watching does not see an alert pop up. According to the documentation:
Under Selenium, JavaScript alerts will NOT pop up a visible alert
dialog.
Selenium does NOT support JavaScript alerts that are generated in a
page's onload() event handler. In this case a visible dialog WILL be
generated and Selenium will hang until someone manually clicks OK.
Both assertAlert and verifyAlert are both based off getAlert(), all of which do the alert 'stuff' in the background. So try adding these functions to ensure that the alert is working, run the script, and then check to see if it works.
A note: this only works if you ensure the test fails before you put in the alert (basic idea of testing, fail first - make test pass).

Categories

Resources