Closed IlfirinPL closed 9 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?
I think they just look like XPath. See the JavaScript implementation for Selenium 1.
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)
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.
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
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...
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?
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
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.
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.
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;
}
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)
pull request 352 https://github.com/rtomac/robotframework-selenium2library/pull/352
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/