robotframework / SeleniumLibrary

Web testing library for Robot Framework
Apache License 2.0
1.39k stars 765 forks source link

SmartClient and SmartGWT #333

Closed IlfirinPL closed 9 years ago

IlfirinPL commented 10 years ago

SmartClient and SmartGWT its not possible to use locator like 'scLocator' Maybe its possible to port keyword "Add Location Strategy" from SeleniumLibrary or extent this this type of strategy to common available strategy. Other solution to allow import of user-extensions.js/user-extensions-ide.js.

Below some links related to this topic

http://www.smartclient.com/smartgwtee-latest/javadoc/com/smartgwt/client/docs/UsingSelenium.html https://github.com/MarkusBernhardt/robotframework-selenium2library-java/issues/1 https://blog.codecentric.de/en/2010/12/testing-smartgwt-applications-with-selenium-and-robot-framework/

emanlove commented 10 years ago

Looking at the codecentric article it looks as if the locators are simply xpath locators. Is there anything unique with SmartClient and SmartGWT elements? Does one use javascript to find those elements?

ombre42 commented 10 years ago

I think they just look like XPath. See the JavaScript implementation for Selenium 1.

IlfirinPL commented 10 years ago

I have example like recorded from selenium IDE type |scLocator=//ListGrid[ID="ChainList"]/filterEditor/editRowForm/item[name=name||title=Chain%20Name||value=test||index=0||Class=TextItem]/element | test

used in robot like Wait Until Page Contains Element xpath=//ListGrid[ID="ChainList"]/filterEditor/editRowForm/item[name=name||title=Chain%20Name||value=test||index=0||Class=TextItem]/element Input Text xpath=//ListGrid[ID="ChainList"]/filterEditor/editRowForm/item[name=name||title=Chain%20Name||value=test||index=0||Class=TextItem]/element test

rise following error

InvalidSelectorException: Message: u'The given selector //ListGrid[ID="ChainList"]/filterEditor/editRowForm/item[name=name||title=Chain%20Name||value=test||index=0||Class=TextItem]/element is either invalid or does not result in a WebElement. The following error occurred:\nInvalidSelectorError: Unable to locate an element with the xpath expression //ListGrid[ID="ChainList"]/filterEditor/editRowForm/item[name=name||title=Chain%20Name||value=test||index=0||Class=TextItem]/element because of the following error:\nSyntaxError: The expression is not a legal expression.' ; Stacktrace: at FirefoxDriver.annotateInvalidSelectorError (file:///d:/temp/tmpyeww35/webdriver-py-profilecopy/extensions/fxdriver@googlecode.com/components/driver-component.js:9592:5) at FirefoxDriver.prototype.findElementsInternal (file:///d:/temp/tmpyeww35/webdriver-py-profilecopy/extensions/fxdriver@googlecode.com/components/driver-component.js:9650:5) at FirefoxDriver.prototype.findElements (file:///d:/temp/tmpyeww35/webdriver-py-profilecopy/extensions/fxdriver@googlecode.com/components/driver-component.js:9654:3) at DelayedCommand.prototype.executeInternal/h (file:///d:/temp/tmpyeww35/webdriver-py-profilecopy/extensions/fxdriver@googlecode.com/components/command-processor.js:11612:16) at DelayedCommand.prototype.executeInternal (file:///d:/temp/tmpyeww35/webdriver-py-profilecopy/extensions/fxdriver@googlecode.com/components/command-processor.js:11617:7) at DelayedCommand.prototype.execute/< (file:///d:/temp/tmpyeww35/webdriver-py-profilecopy/extensions/fxdriver@googlecode.com/components/command-processor.js:11559:5)

ombre42 commented 10 years ago

This isn't the first time adding a custom strategy has come up, but I can't remember where it was discussed. Adding custom strategies would be a nice feature to have, and I do not think it would be very hard to implement. @IlfirinPL I would be able to recommend a workaround until adding custom strategies is supported, but I cannot find the production code used for the scLocator - closed source maybe? Custom By for Java WebDriver I cannot find the source for this. A prototype can be found in the forums.

IlfirinPL commented 10 years ago

There are sources http://smartclient.com/builds for smart client but only included driver as jar

below sources for isomorphic-webdriver with Class ByScLocator http://www.speedyshare.com/qBABJ/isomorphic-webdriver.src.zip

emanlove commented 10 years ago

In the back of my head I see using something like Zope interfaces (named "Zope" because it came from Zope but they are not unique to or require Zope to be used). Basically giving people a plug and play interface to add their own locators. Probably overkill but still a thought...

ombre42 commented 10 years ago

I looked at how the Java bindings handle this and how elementfinder works. In the Java bindings, a custom By receives a search context, which could be either a WebElement or WebDriver. The jQuery, your angularJS locators receive nothing but the driver. The filtering is done the same for every locator. For a user locator, S2L should take care of that (and it should probably be refactored if there's no scenario where filtering won't be done). I'm thinking def add_locator_strategy(prefix, method) where method is a callable that takes one argument. That argument may be a webdriver instance or webelement instance (future proofing for the changes you mentioned in the user group). The callable must return a list of webelements. Perhaps I am failing to see the complexity you see?

IlfirinPL commented 10 years ago

I think this adding locator strategy should be sufficient, other part is rising error when element is not found for some reason method like "Wait Until Page Contains Element " shouldn’t rise those type of errors

ombre42 commented 10 years ago

Wait Until Page Contains Element only raises an error on timeout. If there is an unexpected error, though, it is not caught and will bubble up and cause the wait keyword to fail. After mulling over, I don't think only having a single callable is good. It leads to boiler plate code checking if the search context is a web element or a driver. Would be cleaner if the user code has separate methods like find_elements and find_elements_from_webelement. I think we should define an API like RF does for things like listeners and provide an abstract class, but not require it to be used. In the abstract class we could provide a method to make polling with timeout easy to do - see #337.

IlfirinPL commented 10 years ago

I don`t think we should split method into two based on what we search for WebElement or WebDriver. As end user I want to specify xpath and it should be search both areas.

IlfirinPL commented 9 years ago

Maybe its possible to implement in python similar to code below "selenium.setExtensionJs("src/main/resources/user-extensions.js");"

more example code protected static DefaultSelenium selenium;

@BeforeClass
public static void setUp() throws Exception {
    selenium = new DefaultSelenium("localhost", 4444, "*firefox", getBaseUrl());
    selenium.setExtensionJs("src/main/resources/user-extensions.js");
    selenium.start();
    selenium.windowMaximize();
    BaseSeleniumChecks.selenium = selenium;
}
IlfirinPL commented 9 years ago

I have method that would have to be added to elementfinder.py to allow support of scLocator.

it required 2 modification add next strategy in method init 'scLocator': self._find_by_sc_locator,

and add method itself

def _find_by_sc_locator(self, browser, criteria, tag, constraints): js = "return isc.AutoTest.getElement('%s')" % criteria.replace("'", "\'") return self._filter_elements( [browser.execute_script(js)], tag, constraints)

IlfirinPL commented 9 years ago

pull request 352 https://github.com/rtomac/robotframework-selenium2library/pull/352