59502

Powershell Website Automation: Javascript Popup Box Freeze

Question:

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" }

Answer1:

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:

<ol><li>

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.

</li> <li>

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.

</li> </ol>

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.

Answer2:

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:

<a href="http://autobrowse.start-automating.com/" rel="nofollow">http://autobrowse.start-automating.com/</a>

Use this instead, and you will sidestep the issue.

Hope this helps

Answer3:

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}') } }

Recommend

  • Retrieving data from SQL server 2008r2 using winforms
  • ASPNET: Make sure that the class defined in this code file matches the 'inherits' attribut
  • Pass viewmodel with two objects to controller using Json
  • Python Selenium (waiting for frame, element lookups)
  • Powershell Website Automation: Javascript Popup Box Freeze
  • Setting an image.Source from a resource file
  • Font gets changed in Android Studio preview but not in the Emulator/device
  • WinForms: How to check for minimum amount of characters in textbox in C#?
  • web controls are not recognizing in the respective codebehind class
  • The type or namespace name 'User' could not be found (are you missing a using directive or
  • What does Queue() function do in Chisel?
  • How to run background service after every 5 sec not working in android 5.1?
  • Capture reload/endrequest event after server redirect to download file
  • Ionic run android - Internal Error
  • Accessing another variable in the same class with a click event
  • Why can't UI components be accessed from a backgroundworker?
  • How to getText() from the input field of an angularjs Application
  • Disable Kendo Autocomplete
  • CakePHP 2.0.4 - findBy magic methods with conditions
  • Django rest serializer Breaks when data exists
  • Recording logins for password protected directories
  • Is there any way to access browser form field suggestions from JavaScript?
  • C# - Serializing and deserializing static member
  • Sending data from AppleScript to FileMaker records
  • using conditional logic : check if record exists; if it does, update it, if not, create it
  • How to include full .NET prerequisite for Wix Burn installer
  • python regex in pyparsing
  • Getting error when using KSoap library to consume .NET web services
  • Android Google Maps API OnLocationChanged only called once
  • Is it possible to post an object from jquery to bottle.py?
  • sending mail using smtp is too slow
  • Busy indicator not showing up in wpf window [duplicate]
  • Why is Django giving me: 'first_name' is an invalid keyword argument for this function?
  • How can I use `wmic` in a Windows PE script?
  • How can I use threading to 'tick' a timer to be accessed by other threads?