George Kendros
George Kendros

Reputation: 824

Can powershell wait until IE is DOM ready?

I'm currently writing a script and I'm using

while($IE.busy) {Start-Sleep 1}

to wait for the page to be ready.

Once the page is ready my script fills out and submits a form. I've been running into problems because (I think) IE reports that it's done when the page is loaded but before the document has been rendered (which causes the script to error out). My current workaround is to add a 4 second wait time after the page loads but I'd feel more comfortable with a method that isn't time based if possible.

Upvotes: 8

Views: 18106

Answers (2)

Nathan Beam
Nathan Beam

Reputation: 41

I found this thread really helpful and ended up coming up with a slightly different solution. I am pretty new to powershell so hopefully I didn't make a hash of it but this worked really well for me.

I used a "while" statement so that my condition would loop while true:

while($ie.document.body.outerHTML -notMatch "<input type=`"submit`" value=`"Continue`">") {start-sleep -m 100};

In this case I was matching against a portion of the "outerHTML" part of the body. As long as I don't match the specified text the script will wait and continue to loop the match check.

I like this solution as I could do it in more or less one line of code and I like to keep things compact where possible. Hopefully this is helpful to someone else. Like the OP I found ie.readystate to be very finnicky/unreliable but I really didn't want to just put a static sleep timer in.

Also, while Chrome is an excellent way to break a page down. You can also print to the console window once you have IE running programmatically by simply running:

$ie.document.body

You can dig through visually and then filter down to the section you want which should speed up your matching (I would guess), which is what I did in my code example above.

The only other thing I will note... I think -match uses "regex" because I had to use the tick mark (ex. ` ) to escape the quotes that were part of the string I was matching.

Cheers!

Here is a good reference on "while" logic: http://www.powershellpro.com/powershell-tutorial-introduction/logic-using-loops/

Upvotes: 4

andyb
andyb

Reputation: 2772

Here's how I do this.

Step 1 - Identify a web page element that only appears once the page is fully rendered. I did this using the Chrome developer tools 'Elements' view which shows the DOM view.

Step 2 - Establish a wait loop in the script which polls for the existence of the element or the value of text inside that element.

# Element ID to check for in DOM
$elementID = "systemmessage"

# Text to match in elemend
$elementMatchText = "logged in"

# Timeout
$timeoutMilliseconds = 5000

$ie = New-Object -ComObject "InternetExplorer.Application"

# optional
$ie.Visible = $true

$ie.Navigate2("http://somewebpage")
$timeStart = Get-Date
$exitFlag = $false

do {

    sleep -milliseconds 100

    if ( $ie.ReadyState -eq 4 ) {

        $elementText = (($ie.Document).getElementByID($elementID )).innerText
        $elementMatch = $elementText -match $elementMatchText

        if ( $elementMatch ) { $loadTime = (Get-Date).subtract($timeStart) }

    }

    $timeout = ((Get-Date).subtract($timeStart)).TotalMilliseconds -gt $timeoutMilliseconds
    $exitFlag = $elementMatch -or $timeout

} until ( $exitFlag )

Write-Host "Match element found: $elementMatch"
Write-Host "Timeout: $timeout"
Write-Host "Load Time: $loadTime"

Upvotes: 8

Related Questions