Sign in to follow this  
Followers 0
mike88

IE and identical buttons with same class name and no name, id, nor label. Impossible to click?

20 posts in this topic

Hi,

I have a web page that seems to dynamically create all the buttons the same way. As result, they all have same classes and names. If I try to click them, nothing happens.

I am currently testing with following script:

Local $oBtns = _IETagNameGetCollection($oIE, "button")


For $oBtn In $oBtns

    If String($oBtn.classname) == "this is the popular button name" Then

        $oFound = $oBtn

        If IsObj($oFound) Then

            _IEAction($oBtn, "click")

            ConsoleWrite($oBtn.classname & @CRLF)

        EndIf

    EndIf

Next

Classname is populated correctly. Unfortunately, the _IEAction click does not apply on any of the them.

DOM Explorer sees the buttons following way:

<button class="this is the popular button name"></button>

No name, no id, no label.

Is there any way to click these buttons?

Is there any way to differentiate the buttons from each other?

Thanks

Share this post


Link to post
Share on other sites



Best way to get help on this is post the website.

 

Hi,

unfortunately the site is private. But I am eager to test for you :)

Share this post


Link to post
Share on other sites

Yes, company partner web site behind firewalls. The GUI in some parts is really crappy so I was thinking of making my life easier with autoit.

Share this post


Link to post
Share on other sites

Just because the page is private doesn't mean you can't make a reproducer.

Does this match the sort of page you are working with?

#include <FileConstants.au3>
#include <IE.au3>

Local $sFileName = "reproducer.html"
Local $sPath = @SCriptDir & "/" & $sFileName
Local $sURL = "file:///" & $sPath


IF Not FileExists($sPath) Then
    ; write file
    Local $hFile = FileOpen($sPath, $FO_OVERWRITE)
    FileWrite($hFile, "<html><head><title>Identical Buttons</title></head><body><button class=""btnclass""></button><button class=""btnclass""></button></body></html>")
    FileClose($hFile)
EndIf


Local $oIE = _IECreate($sURL)
Local $oDoc = _IEDocGetObj($oIE)

If Not IsObj($oDoc) Then
    $oIE = _IEAttach($sFileName, "url")
    $oDoc = _IEDocGetObj($oIE)
EndIf


Local $oBtns = _IETagNameGetCollection($oDoc, "button")
For $oBtn In $oBtns
    If String($oBtn.classname) == "btnclass" Then
        $oFound = $oBtn

        If IsObj($oFound) Then
            _IEAction($oBtn, "click")
            ConsoleWrite($oBtn.classname & " " & @error & @CRLF)
        EndIf
    EndIf
Next

_IEQuit($oIE)

Share this post


Link to post
Share on other sites

 

Just because the page is private doesn't mean you can't make a reproducer.

Does this match the sort of page you are working with?

#include <FileConstants.au3>
#include <IE.au3>

Local $sFileName = "reproducer.html"
Local $sPath = @SCriptDir & "/" & $sFileName
Local $sURL = "file:///" & $sPath


IF Not FileExists($sPath) Then
    ; write file
    Local $hFile = FileOpen($sPath, $FO_OVERWRITE)
    FileWrite($hFile, "<html><head><title>Identical Buttons</title></head><body><button class=""btnclass""></button><button class=""btnclass""></button></body></html>")
    FileClose($hFile)
EndIf


Local $oIE = _IECreate($sURL)
Local $oDoc = _IEDocGetObj($oIE)

If Not IsObj($oDoc) Then
    $oIE = _IEAttach($sFileName, "url")
    $oDoc = _IEDocGetObj($oIE)
EndIf


Local $oBtns = _IETagNameGetCollection($oDoc, "button")
For $oBtn In $oBtns
    If String($oBtn.classname) == "btnclass" Then
        $oFound = $oBtn

        If IsObj($oFound) Then
            _IEAction($oBtn, "click")
            ConsoleWrite($oBtn.classname & " " & @error & @CRLF)
        EndIf
    EndIf
Next

_IEQuit($oIE)

That was it exactly.

While wondering why I did not get your IE object to work, I updated AutoIT and that fixed the original problem....

Sorry about the hassle everyone and thank you for your help! :) I feel embarrassed now..

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Most of the time, if there are the same class/id/name string names, the tag has a unique parent id/name/class/etc.

eg.

<div id=uniqueName><input class="nonuniqueName" type="button"></div>

You could get the object of the uniqueName, then its child and you have the unique button for that tag without bleeding into all the other ones.

This is necessary for CSS rendering/positioning/etc.

In this >library there are some class functions.  Like how you use the _IEGetObjByName() function, you could use the _IEJS_JSGetObjByClassName() and use the "Index" parameter if you know which index the button falls into in the html.

Edit:

Evidently Mat hit what you needed, I'm unsure what it was that did it atm though lol.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

Actually I am still wondering about how differentiating the buttons from each other.

_IEJS_JSGetObjByClassName() and index suggestion might do the trick. Thank you very much!

Share this post


Link to post
Share on other sites

Hi,

I used the reproducer in combination with the IEJS.

Added:

#include <IEJS.au3>

$testing = _IEJS_JSGetObjByClassName($oDoc, "btnclass", "button", 1)

#include <FileConstants.au3>
;#include <IE.au3>
#include <IEJS.au3>

Local $sFileName = "reproducer.html"
Local $sPath = @SCriptDir & "/" & $sFileName
Local $sURL = "file:///" & $sPath


IF Not FileExists($sPath) Then
    ; write file
    Local $hFile = FileOpen($sPath, $FO_OVERWRITE)
    FileWrite($hFile, "<html><head><title>Identical Buttons</title></head><body><button class=""btnclass""></button><button class=""btnclass""></button></body></html>")
    FileClose($hFile)
EndIf


Local $oIE = _IECreate($sURL)
Local $oDoc = _IEDocGetObj($oIE)

If Not IsObj($oDoc) Then
    $oIE = _IEAttach($sFileName, "url")
    $oDoc = _IEDocGetObj($oIE)
EndIf

Local $oBtns = _IETagNameGetCollection($oDoc, "button")
For $oBtn In $oBtns
    If String($oBtn.classname) == "btnclass" Then
        $oFound = $oBtn

        If IsObj($oFound) Then
            _IEAction($oBtn, "click")
            ConsoleWrite($oBtn.classname & " " & @error & @CRLF)
        EndIf
    EndIf
Next

$testing = _IEJS_JSGetObjByClassName($oDoc, "btnclass", "button", 1)

_IEQuit($oIE)

This results to:

btnclass 0
btnclass 0
!>19:42:55 AutoIt3.exe ended.rc:-1073741571
+>19:42:55 AutoIt3Wrapper Finished.
>Exit code: 3221225725    Time: 7.474

The failing line is of course the only one I added. Did I understand something wrong about the function syntax (IEObject, class name, class, occurense)?

Share this post


Link to post
Share on other sites

I'd agree with SmOke_N

If there is infact some unique parent, you can use my signature to grab the child, like this (an example of finding the input with SmOke_N's strucutre.

$xpath = "//div[@id='uniqueName']/input[@class='nonuniqueName']"

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

 

The failing line is of course the only one I added. Did I understand something wrong about the function syntax (IEObject, class name, class, occurense)?

Unless you mean the fact that you didn't use the _iejs_jsgetobjbyclassname() function really at all... i guess not?

#include <FileConstants.au3>
;#include <IE.au3>
#include <IEJS.au3>

Local $sFileName = "reproducer.html"
Local $sPath = @SCriptDir & "/" & $sFileName
Local $sURL = "file:///" & $sPath


IF Not FileExists($sPath) Then
    ; write file
    Local $hFile = FileOpen($sPath, $FO_OVERWRITE)
    FileWrite($hFile, "<html><head><title>Identical Buttons</title></head><body><button class=""btnclass""></button><button class=""btnclass""></button></body></html>")
    FileClose($hFile)
EndIf


Local $oIE = _IECreate($sURL)
Local $oDoc = _IEDocGetObj($oIE)

If Not IsObj($oDoc) Then
    $oIE = _IEAttach($sFileName, "url")
    $oDoc = _IEDocGetObj($oIE)
EndIf

Local $oBtn = _IEJS_JSGetObjByClassName($oDoc, "btnclass", "button", 1)
If Not IsObj($oBtn) Then
    ConsoleWrite("oops" & @CRLF)
    Exit 1
EndIf

ConsoleWrite("What are you waiting for?" & @CRLF)
_IEQuit($oIE)

BTW, what version of IE are you using?


Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

Unfortunately it still fails to line

Local $oBtn = _IEJS_JSGetObjByClassName($oDoc, "btnclass", "button", 1)

The script does not go past that line (tried with consolewrites before and after). The same errors persist.

Share this post


Link to post
Share on other sites
BTW, what version of IE are you using?

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

I kept getting the activex popup with the code above, after debugging that, I noticed I left a debug string in the javascript for that function... so I'll be updating my code shortly with a fix for that and one other thing on the major version function.


Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

Sorry forgot to answer: I am using IE11

Share this post


Link to post
Share on other sites

Re-installed AutoIT now with x64 binaries to test if I would get better results.

"C:\Program Files (x86)\AutoIt3\Include\IEJS.au3" (615) : ==> Recursion level has been exceeded - AutoIt will quit to prevent stack overflow.:
Func _IEJS_GetObjType(ByRef $oObj)

->19:08:14 AutoIt3.exe ended.rc:1
+>19:08:14 AutoIt3Wrapper Finished.
>Exit code: 1    Time: 2.984

It failed on the same line but probably gives more information about the root cause than the previous one did.

Share this post


Link to post
Share on other sites

#19 ·  Posted (edited)

I have a comment on the _IEJS_CallObjExecScript() down by the Eval call.  If both failed, it is the only place where a recursion would happen.

Why would they both fail?  Your browser is not allowing javascript injection or the browsers javascript interpreter is broken.

Why?:

1.  You haven't enabled javascript.

2.  There was an update on Dec 18 (if you check the IE11 posts around the internet and on this forum), you need to uninstall that.

https://www.google.com/webhp?#q=KB3025390

Edited by SmOke_N
1 person likes this

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

It was the hotfix. Your UDF works like a charm :)

Thank you very much for your efforts and for your contribution!

Edit: and thank you Mat for the reproducer

Edited by mike88

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
Sign in to follow this  
Followers 0