How to properly access elements of Internet Explorer?

0

I have a script that tests whether one of our websites is working properly.

  1. Test 1: It checks the HTTP status. (no problem here)
  2. Test 2: It checks whether user authorization is working because we have had issues with this in the past.

Then it waits one hour and runs both tests again.

The overall structure of the script is as follows (pseudocode):

while (1 -eq 1) {
    test1
    if ($result -eq "pass") {
        test2
    }
    start-sleep -seconds 3600
}

Test 2 is where the problem occurs. How this test works is: navigate to the login page, enter credentials, click login button. Check URL, as successful login leads to a different URL from the login page. This works fine, except on (seemingly random) loops it cannot access the elements of the page: the username and passwords fields and the login button. The exceptions that get thrown vary depending on how I change the code around to try to fix the problem.

Some error messages I've gotten include:

System.Runtime.InteropServices.COMException The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)

System.Runtime.InteropServices.COMException The property 'value' cannot be found on this object. Verify that the property exists and can be set.

System.Runtime.InteropServices.COMException OperationStopped: (:) [], COMException HResult: -2147352319 No such interface supported

System.Runtime.InteropServices.COMException OperationStopped: (:) [], COMException HResult: -2147352319 This command is not supported.

The offending code is anything that tries to access a page element with getElementByID, for example:

$ie.Document.getElementByID("username").value = $userame

Again, the weird thing is that the code runs fine for hours and hours... but then, usually in the middle of night, it randomly becomes unable to access the page elements.

Following is the full code of Test 2 in case that helps:

$ie = New-Object -ComObject "internetExplorer.Application"
#$ie.Visible = $true
$ie.navigate2($loginPage)
while ($ie.busy -eq $true) {start-sleep -seconds 1}
$ie.Document.getElementByID("username").value = $username
$ie.Document.getElementByID("password").value = $password
$ie.Document.getElementByID("login-button").click()
while ($ie.busy -eq $true) {start-sleep -seconds 1}
if ($ie.Document.url -eq $landingPage) {
    #success
} else {
    #failure
}
$ie.quit()
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($ie) | out-null
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
$process = get-process -name "iexplore"
while ($process) {
    try {
        stop-process -name "iexplore" -ea stop
    } catch [Microsoft.PowerShell.Commands.ProcessCommandException] {
        #do nothing
    }
    try {
        $process = get-process -name "iexplore" -ea stop
    } catch [Microsoft.PowerShell.Commands.ProcessCommandException] {
        $process = $null
    }
}
powershell
dom
com
internet-explorer-11
asked on Stack Overflow Feb 13, 2019 by Johnny Tisdale • edited Feb 20, 2019 by Johnny Tisdale

1 Answer

0

Until I can figure out what the problem is, I've implemented a workaround. I put the offending code in a try block. In the catch block, I restart the script. Following is not exactly how it is implemented in my script but it gives you the idea:

try {
    $ie.Document.getElementByID("username").value = $username
} catch {
    start powershell {$scriptPath}
    exit
}

When the script restarts, the elements of the page can once again be accessed with getElementByID.

answered on Stack Overflow Feb 15, 2019 by Johnny Tisdale

User contributions licensed under CC BY-SA 3.0