tonedeaf

IE Automation using jQuery

16 posts in this topic

#1 ·  Posted (edited)

I use AutoIt exclusively nowdays for web automation and found myself repeatedly using Internet Explorer methods document.getElementById(), document.getElementsByTagName(), then testing the elements returned for some conditions (using a loop) and extracting the data.

With jQuery becoming the de-facto DOM Selector javascript library, I wondered if it was possible to "insert" jQuery into an IE page, then calling the rich jQuery API to select DOM elements. This would reduce the no. of lines in my AutoIt script drastically.

One option is to use Dale Holm's Internet Explorer Automation Library, which comes with AutoIt. But it doesn't offer the feature rich API like jQuery.

[** Dale is working on also adding support for jQuery in IE Automation, I hope he can help resolve some of the issues in DOM Manipulation using jQuery **]

Download the latest jQuery library: http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js

Rename it to "jquery.js" and save it in the same folder with the script below.

Opt('MustDeclareVars', 1)

Local $objCOMError, $objAppIE, $jQuery

$objCOMError = ObjEvent("AutoIt.Error", "_COMErrorHandler")

$objAppIE = ObjCreate("InternetExplorer.Application")
$objAppIE.visible = True

_GetFeaturedGoogleVideo($objAppIE)

Func _GetFeaturedGoogleVideo($objAppIE)
    $objAppIE.navigate('http://video.google.com')
    $jQuery = _insertjQuery($objAppIE)

 ; Testing DOM selection functions. All DOM selection functions seem to work!   
    ConsoleWrite('Featured Video: ' & $jQuery('table[class=hot_videos_body] div[class=title]').get(0).innerText & @LF)
    ConsoleWrite('Direct Link: ' & $jQuery('table[class=hot_videos_body] a[id=hs_title_link]').get(0).getAttribute('href') & @LF)

 ; Testing some DOM manipulation functions, some work and the others don't. Don't know why                  
    $jQuery("<p>What's Cooking!</p>").appendTo('body'); works
    $jQuery('body').hide(); doesn't work :(

EndFunc

Func _insertjQuery($objAppIE)
    Local $objWindow, $objHead, $objScript
    
    _IEPageLoadWait($objAppIE)
    
    $objWindow = $objAppIE.document.parentWindow
    $objHead = $objAppIE.document.getElementsByTagName('head').item(0)
    If Not(IsObj($objwindow.jQuery)) Then
        $objScript = $objAppIE.document.createElement('script')
        $objScript.type = 'text/javascript'
        $objScript.defer = 'defer'
        $objScript.text = FileRead(@ScriptDir & '\jquery.js')
        $objHead.appendChild($objScript)
        
        While Not(IsObj($objwindow.jQuery))
            Sleep(100)
        WEnd
        
        $objwindow.jQuery.noConflict()
    EndIf
    
    Return $objwindow.jQuery
EndFunc

Func _IEPageLoadWait($objAppIE)
    Do
        Sleep(100)
    Until ($objAppIE.readyState = 'complete' Or $objAppIE.readyState = 4)
    Do
        Sleep(100)
    Until ($objAppIE.document.readyState = 'complete' Or $objAppIE.document.readyState = 4)
EndFunc

Func _COMErrorHandler()
    Switch $objCOMError.number
    Case -2147352570
        Return 0
    Case Else
; Don't use central errorhandler
        MsgBox(8240, "Automation Error", "Unhandled COM Automation Error." & @CRLF & @CRLF & _
                    "This operation resulted in an unhandled error." & @CRLF & @CRLF & _
                    "Technical Information: " & @CRLF & _
                    "Error Number: " & $objCOMError.number & @CRLF & _
                    "Error Description: " & $objCOMError.winDescription & @CRLF & _
                    "Line Number: " & $objCOMError.scriptLine & @CRLF & @CRLF & _
                    "Contact technical support for furthur help.")
        Exit
    EndSwitch               
EndFunc

Update (20-Apr-09): Improved the jQuery injection routine, now uses a local file instead of linking to Google CDN network. The routine checks if jQuery is already being used by the website, and skips injection is if it does. Also, uses the jQuery.noConflict() to avoid problems with existing javascript libraries used on the web page.

Update (30-Sep-08): Identified some issues with jQuery wrapped sets methods not working correctly when invoked from AutoIT. the DOM selector methods work but some DOM manipulation methods don't work when called from within AutoIT. Investigating, will post updated code as soon as I resolve the issue. The issue may be with the AutoIT COM translation of jQuery javascript objects.

Update (22-Sep-08): Updated _IEPageLoadWait() function to check for document readyState. Updated _insertjQuery() function to define default location of jQuery.js and call _IEPageLoadWait()

Edited by tonedeaf

Share this post


Link to post
Share on other sites



This is great! Good work man. Absolutely perfect for grabin data of dynamic pages with lil code. :)

Share this post


Link to post
Share on other sites

This looks quite compelling. I've been doing some work focusing on Prototype and Scriptaculous, but I'll take a look at jQuery now as well.

Dale


Free Internet Tools: DebugBar, AutoIt IE Builder, HTTP UDF, MODIV2, IE Developer Toolbar, IEDocMon, Fiddler, HTML Validator, WGet, curl

MSDN docs: InternetExplorer Object, Document Object, Overviews and Tutorials, DHTML Objects, DHTML Events, WinHttpRequest, XmlHttpRequest, Cross-Frame Scripting, Office object model

Automate input type=file (Related)

Alternative to _IECreateEmbedded? better: _IECreatePseudoEmbedded  Better Better?

IE.au3 issues with Vista - Workarounds

SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y Doesn't work needs to be ripped out of the troubleshooting lexicon. It means that what you tried did not produce the results you expected. It begs the questions 1) what did you try?, 2) what did you expect? and 3) what happened instead?

Reproducer: a small (the smallest?) piece of stand-alone code that demonstrates your trouble

Share this post


Link to post
Share on other sites
Update (22-Sep-08): Updated _IEPageLoadWait() function to check for document readyState. Updated _insertjQuery() function to define default location of jQuery.js and call _IEPageLoadWait()

Share this post


Link to post
Share on other sites

where can we download that beautiful code please ?

Share this post


Link to post
Share on other sites

Did anyone squirrel away a copy of this code? I came back here to find it today and was disappointed to see it not here. I've sent a pm to tonedeaf, but here has not been here for a while...

thanks,

Dale


Free Internet Tools: DebugBar, AutoIt IE Builder, HTTP UDF, MODIV2, IE Developer Toolbar, IEDocMon, Fiddler, HTML Validator, WGet, curl

MSDN docs: InternetExplorer Object, Document Object, Overviews and Tutorials, DHTML Objects, DHTML Events, WinHttpRequest, XmlHttpRequest, Cross-Frame Scripting, Office object model

Automate input type=file (Related)

Alternative to _IECreateEmbedded? better: _IECreatePseudoEmbedded  Better Better?

IE.au3 issues with Vista - Workarounds

SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y Doesn't work needs to be ripped out of the troubleshooting lexicon. It means that what you tried did not produce the results you expected. It begs the questions 1) what did you try?, 2) what did you expect? and 3) what happened instead?

Reproducer: a small (the smallest?) piece of stand-alone code that demonstrates your trouble

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

I've re-posted the code, I forgot to update the forum it when I was checking for some incompatibilities between IE, jQuery and AutoIt. However, I think I stand a better chance if others users also try it and figure out why some jQuery DOM Manipulation functions won't work.

Edited by tonedeaf

Share this post


Link to post
Share on other sites

any updates? this is a great project

Share this post


Link to post
Share on other sites

Hi...Any update on adding jQuery feature to AutoIt? I work with some complex web applications and having jQuery support to find widgets would make the awesome IE UDF super Awesome.

Share this post


Link to post
Share on other sites

Share this post


Link to post
Share on other sites

Thank you! Looking forward for it! Please let me know if i could help.

Share this post


Link to post
Share on other sites

@Vishal85

Help ? Sure try to post some examples and share.

#include <IE.au3>

$objAppIE = _IECreate ()
_IENavigate ($objAppIE, "[url="http://www.autoitscript.com"]http://www.autoitscript.com[/url]")

$jQuery = _InsertjQuery($objAppIE)

If IsObj($jQuery) Then
MsgBox(0,"Version","The JQuery Libr. Version is : " & $jQuery.fn.jquery & @CRLF & $jQuery.now())
EndIf

Func _InsertjQuery($objAppIE)
Local $objWindow, $objHead, $objScript
If IsObj($objAppIE) Then
$objWindow = $objAppIE.document.parentWindow

$objHead = $objAppIE.document.getElementsByTagName('head').item(0)

If Not(IsObj($objwindow.jQuery)) Then
ConsoleWrite(IsObj($objwindow.jQuery) & @CRLF)
$objScript = $objAppIE.document.createElement('script')
$objScript.type = 'text/javascript'
$objScript.defer = 'defer'
$Script = FileRead(@ScriptDir & '\jquery-1.9.1.min.js')
$objScript.text = $Script
$objHead.appendChild($objScript)

While Not(IsObj($objwindow.jQuery))
Sleep(100)
WEnd

$objwindow.jQuery.noConflict()
EndIf

Return $objwindow.jQuery
EndIf
EndFunc

You see in this example I load version 1.9.1 but it reports 1.8.x becayse the foum already had a JQUery lib. Loaded.

Enjoy

Rgds

ptrex

Share this post


Link to post
Share on other sites

This example reports version 1.9.1 for me and can repeat the same version by button "Version".

Script loads file "jquery.js" (Version 1.9.1) from script directory:

#include <GUIConstants.au3>
#include <WindowsConstants.au3>

Global $WGui = 600, $HGui = 460
Local $objAppIE, $jQuery

$hWnd = GUICreate("jQuery Test, 2013", $WGui, $HGui, 0, 0)

$objAppIE = ObjCreate("Shell.Explorer.2")
$objAppIE.visible = True

$GUIActiveX = GUICtrlCreateObj($objAppIE, 10, 10, $WGui-20, $HGui-60)
$objAppIE.navigate("about:blank")
$objAppIE.navigate("http://www.autoitscript.com/forum/topic/81025-ie-automation-using-jquery/")
$Version = GUICtrlCreateButton("Version",($WGui-80)/2, $HGui-30, 80, 20)
$jQuery = _InsertjQuery($objAppIE)
GuiSetState()

If IsObj($jQuery) Then
MsgBox(0,"Version","The JQuery Libr. Version is : " & $jQuery.fn.jquery & @CRLF & $jQuery.now())
EndIf

While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
     ExitLoop
Case $Version
$jQuery = _InsertjQuery($objAppIE)
If IsObj($jQuery) Then MsgBox(0,"Version","The JQuery Libr. Version is : " & $jQuery.fn.jquery & @CRLF & $jQuery.now())
EndSwitch
WEnd
GUIDelete()
Exit

Func _InsertjQuery($objAppIE)
Local $objWindow, $objHead, $objScript
If IsObj($objAppIE) Then
$objWindow = $objAppIE.document.parentWindow
$objHead = $objAppIE.document.getElementsByTagName('head').item(0)

If Not(IsObj($objwindow.jQuery)) Then
ConsoleWrite(IsObj($objwindow.jQuery) & @CRLF)
$objScript = $objAppIE.document.createElement('script')
$objScript.type = 'text/javascript'
$objScript.defer = 'defer'
$Script = FileRead(@ScriptDir & '\jquery.js')
$objScript.text = $Script
$objHead.appendChild($objScript)

While Not(IsObj($objwindow.jQuery))
Sleep(100)
WEnd

$objwindow.jQuery.noConflict()
EndIf

Return $objwindow.jQuery
EndIf
EndFunc

The point of world view

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

A basic example of Jquery interactions with IE.

Set text to a button

Set text to an input text

Submit a google search

Filtering by class for get only results urls

Global $objAppIE, $jQuery, $jQueryFilePath = @ScriptDir & '\jquery-1.9.1.js'
Global $oMyError = ObjEvent ( 'AutoIt.Error', '_MyErrFunc' )

If Not FileExists ( $jQueryFilePath ) Then InetGet ( 'http://code.jquery.com/jquery-1.9.1.js', $jQueryFilePath )
$objAppIE = ObjCreate ( 'InternetExplorer.Application' )
$objAppIE.visible = True
$objAppIE.navigate ( 'http://www.google.com/' )

$jQuery = _InsertJQuery ( $objAppIE )
If IsObj ( $jQuery ) Then
    $jQuery ( ':input[id="gbqfba"]' ).text ( 'Search With Bing' ) ; set text button
    Sleep ( 1000 ) ; just for see changes
    $jQuery ( ':input[id="gbqfq"]' ).val ( 'autoit' ) ; set input text
    Sleep ( 1000 ) ; just for see changes
    $jQuery ( ':input[id="gbqfba"]' ).submit ( ) ; submit
    _IEPageLoadWait ( $objAppIE )
    Do
        $aLinks = $jQuery ( '.l' ).get ( ) ; filtering by class for get only results urls.
    Until $aLinks.length
    ConsoleWrite ( '! Results Nb : ' & $aLinks.length & @Crlf )
    $i=0
    For $aLink In $aLinks
        $i+=1
        ConsoleWrite ( '+ ' & $i & ' $aLink.href : ' & $aLink.href & @Crlf )
    Next
EndIf

Func _InsertjQuery ( $objAppIE )
    Local $objWindow, $objHead, $objScript
    _IEPageLoadWait ( $objAppIE )
    If IsObj ( $objAppIE ) Then
        $objWindow = $objAppIE.document.parentWindow
        $objHead = $objAppIE.document.getElementsByTagName ( 'head' ).item ( 0 )
        If Not IsObj ( $objwindow.jQuery ) Then
            $objScript = $objAppIE.document.createElement ( 'script' )
            $objScript.type = 'text/javascript'
            $objScript.language = 'javascript'
            $objScript.defer = 'defer'
            $Script = FileRead ( $jQueryFilePath )
            $objScript.text = $Script
            $objHead.appendChild ( $objScript )
            While Not ( IsObj ( $objwindow.jQuery ) )
                Sleep ( 100 )
            WEnd
            $objwindow.jQuery.noConflict ( )
        EndIf
        Return $objwindow.jQuery
    EndIf
EndFunc ;==> _InsertjQuery ( )

Func _IEPageLoadWait ( $objAppIE )
    Do
        Sleep ( 50 )
    Until $objAppIE.readyState = 'complete' Or $objAppIE.readyState = 4
    Do
        Sleep ( 50 )
    Until $objAppIE.document.readyState = 'complete' Or $objAppIE.document.readyState = 4
    Do
        Sleep ( 50 )
    Until Not $objAppIE.busy
EndFunc ;==> _IEPageLoadWait ( )

Func _MyErrFunc ( )
    $HexNumber = Hex ( $oMyError.number, 8 )
    If $HexNumber = 80020006 Then Return
    Msgbox ( 0, '', 'We intercepted a COM Error !' & @CRLF & 'Number is: ' & $HexNumber & @CRLF & 'Windescription is: ' & $oMyError.windescription & @CRLF & 'Line Number: ' & $oMyError.scriptLine & @CRLF, 3 )
    Exit
Endfunc ;==> _MyErrFunc ( )

Edit : work on IE8/W7 but can't get it on IE7/XP and IE9/W7 ( with IE set with same default settings )

Have removed link to http://code.jquery.com/jquery-latest.js cause jQuery team announced that jQuery 2.0,

which is scheduled for 2013, removes support for IE 6/7/8 for some features.

Edited by wakillon

AutoIt 3.3.14.2 X86 - SciTE 3.6.0WIN 8.1 X64 - Other Example Scripts

Share this post


Link to post
Share on other sites

Hello,
Isn't work for me !

Share this post


Link to post
Share on other sites

#16 ·  Posted

Hi, this example is not working for me.

i can see it inserts jquery with script tag but it stays in below loop:

how we can fix it pls?

While Not(IsObj($objwindow.jQuery))
Sleep(100)
WEnd

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now