MarkusBernhardt / robotframework-selenium2library-java

Java port of the Selenium 2 (WebDriver) Python library for Robot Framework
Apache License 2.0
46 stars 48 forks source link

Feature Request: support Ext.ComponentQuery #4

Closed BenjaminZaiser closed 11 years ago

BenjaminZaiser commented 11 years ago

Hi,

I would like to use Ext.ComponentQuery to easily write locators for ExtJS applications:

Example:

Input Text    extJs=(Ext.ComponentQuery.query("textfield[name='first_name']")[0]).getInputId()    Max
Click Element    extJs=(Ext.ComponentQuery.query("button[text='Save']")[0]).getId()

I think, the "Add Location Strategy" is not applicable, because the arguments are not evaluated.

Please could you add a StrategyEnum to support the ExtJS ComponentQuery, just like you already support e.g. JQuery Sizzle?

Thanks.

MarkusBernhardt commented 11 years ago

Hi, currently I see no reason, why "Add Location Strategy" should not work. Could you try:

Add Location Strategy    extJs    return Ext.ComponentQuery.query(arguments[0]);
Input Text    extJs=textfield[name='first_name']    Max
BenjaminZaiser commented 11 years ago

Thanks for your reply, but your proposal wouldn't solve my problem. Please have a look at my first example again. If you want to Input Text into a textfield, you have to use getInputId() for the correct id of the input field, but if just a button has to be clicked, getId() is sufficient. Therefore Selenium2Library should evaluate the whole javascript code, which is defined as a locator.

MarkusBernhardt commented 11 years ago

Hi Benjamin, this somehow sounds weird. A locator should not return the id of an element, but an element or a list of elements. If I understand you correctly you want the locator do a first call to JavaScript to get the id of the element and then a second call to JavaScript to get the element with this id. Wouldn't it be more straight forward to return the element in the first call? Am I missing something completely? Cheers, Markus

BenjaminZaiser commented 11 years ago

If I understand you correctly you want the locator do a first call to JavaScript to get the id of the element and then a second call to JavaScript to get the element with this id. Exactly!

Ext.ComponentQuery.query(arguments[0])

will return an "ExtJS component" which is most likely just a div instead of a button or an input field. The 'real' fields are somewhere inside the div (and there are a lot of other elements - well, that's the charm of ExtJS...) Selenium cannot execute actions on the div. Therefore I assume the query will return only one element ([0]) and I get the Id() or the InputId() -> those Id's are the ones for the button or the input field and only with those Ids Selenium can work.

MarkusBernhardt commented 11 years ago

Ok. Now I get it. That could be easily done. Will include that and come back to you.

MarkusBernhardt commented 11 years ago

Hi Benjamin,

sorry it took some time to get back to look into that.

One more thing. I could implement that, but I believe it would be better to do the following:

Add Location Strategy    extJs         return window.document.getElementById(Ext.ComponentQuery.query(arguments[0])[0]).getId());
Add Location Strategy    extJsInput    return window.document.getElementById(Ext.ComponentQuery.query(arguments[0])[0]).getInputId());

This leads IMHO to much better readable locators:

Click Element    extJs=button[text='Save']
Input Text       extJsInput=textfield[name='first_name']    Max

Could you please point me to a working site using ExtJS so I can test the locators.

Cheers, Markus

BenjaminZaiser commented 11 years ago

Wow, that's a really nice and elegant solution! Thanks a lot for that. Here is a working example:

*** Settings ***
Library Selenium2Library

*** Variables ***
${URL Application}                  http://dev.sencha.com/deploy/ext-4.0.0/examples/writer/writer.html

*** Test Cases ***

Add Employee
    Add Location Strategy    extJs               return window.document.getElementById((Ext.ComponentQuery.query(arguments[0])[0]).getId());
    Add Location Strategy    extJsButton         return window.document.getElementById((Ext.ComponentQuery.query(arguments[0])[0]).btnEl.id);
    Add Location Strategy    extJsTextfield      return window.document.getElementById((Ext.ComponentQuery.query(arguments[0])[0]).getInputId());
    Open Browser    ${URL Application}  firefox mainbrowser False   None    src/test/robotframework/firefoxprofile/

    Click Button    ${add}
    Capture Page Screenshot

    Input Text  ${inputfield email} Haaalloooo Welt
    Capture Page Screenshot

*** Variables ***
${add}              extJsButton=button[text='Add']
${inputfield email} extJsTextfield=textfield[name='email']
MarkusBernhardt commented 11 years ago

Great that it works for you and many thanks for the example! Would it be ok for you, if I include that as a Unittest in the library?

BenjaminZaiser commented 11 years ago

Of course, feel free to use it wherever you want.

liputao commented 7 years ago

No keyword with name 'return window.document.getElementById((Ext.ComponentQuery.query(arguments[0])[0]).btnEl.id);' found

Always this error?????Anything wrong?