Skip to content

Conversation

@tenwit
Copy link

@tenwit tenwit commented Jan 10, 2013

This allows "jquery" and "sizzle" locator prefixes, which delegate to the window's jQuery. Probably not suitable for merging as-is; I think it would be better if jQuery was provided by selenium2library.

But it is easy and probably* works, so I thought I'd share. Maybe it will inspire someone to enhance it.

  • I have the change working on a work computer, but due to in-house restrictions, I had to type it in by hand on another computer in order to push to github. The other computer doesn't have robot, so I haven't actually tested the re-typed-in code.... sorry!
@hemakannan
Copy link

Hi, Guys, does this mean the latest build of selenium Library will have this? I submitted an issue a while back to have jQuery incorporated back in to selenium2Library of Robot Framework as all our tests in RC use jQuery very heavily. Please advice.

Thank You
Hema

@tenwit
Copy link
Author

tenwit commented Jan 11, 2013

If you build it from my fork, it will work (unless I checked in a typo.. see my comment above!). But I doubt Ryan will merge this; IMO it's not the correct solution, it's just a place to start.

@emanlove
Copy link
Member

I've made some time starting yesterday to review issues for the next release. I will look this over. - Ed

@hemakannan
Copy link

Nice !

@hemakannan
Copy link

Ed, any updates on this?

@emanlove
Copy link
Member

@j1z0 have you gotten a chance to review this implementation for jQuery support? I know you were hesitant with adding in jQuery. (For those who haven't seen the historical discussion about jQuery please review Issue #77.)

@hemakannan
Copy link

Hey Guys
It would be very helpful if jquery support is implemented in RF
selenium2lib just like how it is in RF selenium RC.
On Jan 17, 2013 9:19 AM, "Ed Manlove" notifications@github.com wrote:

@j1z0 https://github.com/j1z0 have you gotten a chance to review this
implementation for jQuery support? I know you were hesitant with adding in
jQuery. (For those who haven't seen the historical discussion about jQuery
please review Issue #77#77
.)


Reply to this email directly or view it on GitHubhttps://github.com//pull/161#issuecomment-12369558.

@emanlove
Copy link
Member

@hemakannan Again this is an upstream choice by the Selenium WebDriver team to remove support for jQuery/sizzle. As this is the robotframework-selenium2library we are tying together existing functionality within WebDriver making it accessible through Robot Framework. So if it doesn't exist within WebDriver I'm not sure we should try to shove it in.

@tenwit Do you have any tests for this?

@hemakannan
Copy link

Hi Ed
Yes we have many tests that use jquery. Selenium never had jquery support i
think. My coworker created this keyword called add location strategy and
packaged it. I was wondering if it would be feasible for RF sel2 to have
that .
On Jan 19, 2013 4:05 PM, "Ed Manlove" notifications@github.com wrote:

@hemakannan https://github.com/hemakannan Again this is an upstream
choice by the Selenium WebDriver team to remove support for jQuery/sizzle.
As this is the robotframework-selenium2library we are tying together
existing functionality within WebDriver making it accessible through Robot
Framework. So if it doesn't exist within WebDriver I'm not sure we should
try to shove it in.

@tenwit https://github.com/tenwit Do you have any tests for this?


Reply to this email directly or view it on GitHubhttps://github.com//pull/161#issuecomment-12461155.

@emanlove
Copy link
Member

@hemakannan Let's see his code as I am wandering if there is a solution that works like @peritus's solution for ajax wait.

The solution in this pull request looks clean, in that is fits into the Sel2Library locator strategy but I guessing that it will fail in that browser.execute_script(js) won't return the same thing as browser.find_elements_by_XXXXXXXXX. That's why I want to see a test for this solution.

@tenwit
Copy link
Author

tenwit commented Jan 19, 2013

I don't, but I'm sure I can cobble a few together in no time; it's just a selector prefix. But not until Tuesday, most likely :(

@emanlove
Copy link
Member

@hemakannan Your missing the point in that all the old SeleniumLibrary did was use the jQuery functionality provided by Selenium RC. And actually this was only implemented by a jQuery plug-in which is why I think you had to use the add_location_strategy in the first place. The SeleniumLibrary wasn't doing anything special but simply acting as a bridge between Robot Framework and the functions provided by Selenium RC. Selenium WebDriver dropped support for jQuery/sizzle thus we don't have anything to bridge to or to connect into directly with Selenium2Library.

What I suspect @tenwit will find in testing this change is that the execute javascript will return success but not return a Selenium WebElement which is what selenium needs to perform any function on like click element. It will be trying to "click successful javascript return value" which is wrong.

@hemakannan
Copy link

I see. Gotcha.
On Jan 19, 2013 6:05 PM, "Ed Manlove" notifications@github.com wrote:

@hemakannan https://github.com/hemakannan Your missing the point in
that all the old SeleniumLibrary did was use the jQuery functionality
provided by Selenium RC. And actually this was only implemented by a jQuery
plug-in which is why I think you had to use the add_location_strategy in
the first place. The SeleniumLibrary wasn't doing anything special but
simply acting as a bridge between Robot Framework and the functions
provided by Selenium RC. Selenium WebDriver dropped support for
jQuery/sizzle thus we don't have anything to bridge to or to connect into
directly with Selenium2Library.

What I suspect @tenwit https://github.com/tenwit will find in testing
this change is that the execute javascript will return success but not
return a Selenium WebElement which is what selenium needs to perform any
function on like click element. It will be trying to "click successful
javascript return value" which is wrong.


Reply to this email directly or view it on GitHubhttps://github.com//pull/161#issuecomment-12462878.

@emanlove
Copy link
Member

@hemakannan I wish it was as simple as doing something like SeleniumLibrary but tying in the locator with the actions is really problematic with Selenium dropping support for jQuery/sizzle.

@hemakannan
Copy link

:( well I hoped to see if it was as easy as adding like selenium 1 lib. All
of our tests have something like "jquery = " which we could easily start
using css=
but it would be with writing new tests.

I just hoped that we could just literally migrate all of our tests like
that we :-)

But looks like its not possible.
Also Ed while we were discussing on this thread i realized that something
like :contains("....") and wild card character would not be possible
either. Correct me if i am wrong because that's another thing we use in our
tests example jquery = *:contains("...")

We created a user keyword like this "wait until page contains elements with
text" that in turn uses wait until page contains element and the above
jquery example.
On Jan 19, 2013 6:18 PM, "Ed Manlove" notifications@github.com wrote:

@hemakannan https://github.com/hemakannan I wish it was as simple as
doing something like SeleniumLibrary but tying in the locator with the
actions is really problematic with Selenium dropping support for
jQuery/sizzle.


Reply to this email directly or view it on GitHubhttps://github.com//pull/161#issuecomment-12463040.

@emanlove
Copy link
Member

@hemakannan xpath has a "similar" 'contains' functionality. I use the quotes around "similar" because I am not sure if jQuery and xpath use the exact same syntax but it is something to look into.

@tenwit
Copy link
Author

tenwit commented Jan 20, 2013

@emanlove I haven't written any tests but I am using this patch while migrating our tests to Selenium2Library. It's working fine, as far as it goes. It only works because we use jQuery on all our pages, of course, but that's good enough for now.

@j1z0
Copy link
Contributor

j1z0 commented Jan 20, 2013

Ok I had a look at the code and here is my .02.

I've written something similar and I'm about 99% sure that the execute_script will indeed return the same thing as find_element. So I think we are OK on that point.

And I like the fact that this is using a separate location strategy so it doesn't interfere will anybody who doesn't want to use it.

Now as tenwit correctly points out in his initial comment you have to have jQuery bundled with your application for this to work. So it doesn't achieve the same functionality that was available in Selenium 1.

Thus since I think that is really the goal I would probably add a check if jQuery exists and if it doesn't exist load it. That way this functionality will work on pages / applications that do not have jQuery installed. The downside of that approach is it requires a second round trip from each and every call, which can really slow things down if your a using a remote connection. Thus a different way would be to have a seperate load_jquery keyword that could be called one before any calls using the jQuery location strategy were made... of course there is an issue if the application uses something like prototype where you need to load jQuery with no conflicts so it doesn't overwrite existing frameworks. The way we got around this in the past was with some code like this:

 def _load_jquery(self): import os logger.info("load jquery") #just the location where we were storing a local copy of jQuery #see comments below this may be better to load directly from the jQuery github page. ROOT = os.path.dirname(__file__) LIB_DIR = os.path.join(ROOT, '..', 'lib') jquery_file = os.path.join(LIB_DIR, "jquery-latest.min.js") jquery_lib = open(jquery_file, 'r').read() #NOTE: I'm loading a special version of jquery that uses $j #so basically we are changing jQuery from using $ to using $j #browser.execute_script("var $j = jQuery.noConflict();") browser = self._current_browser() browser.execute_script(jquery_lib) 

this is less than ideal, because it relies on a modified version of jQuery that exists on users system. We could I guess package jQuery with S2L, but it may be better, just to ignore (or at least document) the potential collision issues (read, don't use with prototype.js) and then we could just pull jQuery directly from github and thus always get the latest version.

The other thing to document / keep in mind here is that execute_script does not honor the implicit_wait functionality built into Selenium 2. So if you really want to do it write you should build in the implict wait functionality into the js script that you call... i.e. put some sort of loop / retry in the jquery.

The ultimate decision I'll leave to however implements it, cause I don't really have time to do it at the moment.

@hemakannan
Copy link

Yes tenwit and Jeremy
Our applications understands jquery very well that's why we have all tests
with query selectors. Can we try to get what you have so far working and
try it at our end please.
On Jan 20, 2013 7:23 AM, "Jeremy Johnson" notifications@github.com wrote:

Ok I had a look at the code and here is my .02.

I've written something similar and I'm about 99% sure that the
execute_script will indeed return the same thing as find_element. So I
think we are OK on that point.

And I like the fact that this is using a separate location strategy so it
doesn't interfere will anybody who doesn't want to use it.

Now as tenwit correctly points out in his initial comment you have to have
jQuery bundled with your application for this to work. So it doesn't
achieve the same functionality that was available in Selenium 1.

Thus since I think that is really the goal I would probably add a check if
jQuery exists and if it doesn't exist load it. That way this functionality
will work on pages / applications that do not have jQuery installed. The
downside of that approach is it requires a second round trip from each and
every call, which can really slow things down if your a using a remote
connection. Thus a different way would be to have a seperate load_jquery
keyword that could be called one before any calls using the jQuery location
strategy were made... of course there is an issue if the application uses
something like prototype where you need to load jQuery with no conflicts so
it doesn't overwrite existing frameworks. The way we got around this in the
past was with some code like this:

def _load_jquery(self): import os logger.info("load jquery") #just the location where we were storing a local copy of jQuery #see comments below this may be better to load directly from the jQuery github page. ROOT = os.path.dirname(__file__) LIB_DIR = os.path.join(ROOT, '..', 'lib') jquery_file = os.path.join(LIB_DIR, "jquery-latest.min.js") jquery_lib = open(jquery_file, 'r').read() #NOTE: I'm loading a special version of jquery that uses $j #so basically we are changing jQuery from using $ to using $j #browser.execute_script("var $j = jQuery.noConflict();") browser = self._current_browser() browser.execute_script(jquery_lib) 

this is less than ideal, because it relies on a modified version of jQuery
that exists on users system. We could I guess package jQuery with S2L, but
it may be better, just to ignore (or at least document) the potential
collision issues (read, don't use with prototype.js) and then we could just
pull jQuery directly from github and thus always get the latest version.

The other thing to document / keep in mind here is that execute_script
does not honor the implicit_wait functionality built into Selenium 2. So if
you really want to do it write you should build in the implict wait
functionality into the js script that you call... i.e. put some sort of
loop / retry in the jquery.

The ultimate decision I'll leave to however implements it, cause I don't
really have time to do it at the moment.


Reply to this email directly or view it on GitHubhttps://github.com//pull/161#issuecomment-12469895.

@j1z0
Copy link
Contributor

j1z0 commented Jan 20, 2013

@hemakannan -- I would suspect that tenwit's fork will work just fine for you. Have you tried your tests against it?

@hemakannan
Copy link

Hey Jeremy. No
How should i use it ?
On Jan 20, 2013 9:03 AM, "Jeremy Johnson" notifications@github.com wrote:

@hemakannan https://github.com/hemakannan -- I would suspect that
tenwit's fork will work just fine for you. Have you tried your tests
against it?


Reply to this email directly or view it on GitHubhttps://github.com//pull/161#issuecomment-12471001.

@j1z0
Copy link
Contributor

j1z0 commented Jan 20, 2013

after you have downloaded / installed the fork, you just use a locator that starts with jquery= or sizzle= and that should trigger the query support.

Cheers,
Jeremy

On Jan 20, 2013, at 9:54 PM, hemakannan wrote:

Yes tenwit and Jeremy
Our applications understands jquery very well that's why we have all tests
with query selectors. Can we try to get what you have so far working and
try it at our end please.
On Jan 20, 2013 7:23 AM, "Jeremy Johnson" notifications@github.com wrote:

Ok I had a look at the code and here is my .02.

I've written something similar and I'm about 99% sure that the
execute_script will indeed return the same thing as find_element. So I
think we are OK on that point.

And I like the fact that this is using a separate location strategy so it
doesn't interfere will anybody who doesn't want to use it.

Now as tenwit correctly points out in his initial comment you have to have
jQuery bundled with your application for this to work. So it doesn't
achieve the same functionality that was available in Selenium 1.

Thus since I think that is really the goal I would probably add a check if
jQuery exists and if it doesn't exist load it. That way this functionality
will work on pages / applications that do not have jQuery installed. The
downside of that approach is it requires a second round trip from each and
every call, which can really slow things down if your a using a remote
connection. Thus a different way would be to have a seperate load_jquery
keyword that could be called one before any calls using the jQuery location
strategy were made... of course there is an issue if the application uses
something like prototype where you need to load jQuery with no conflicts so
it doesn't overwrite existing frameworks. The way we got around this in the
past was with some code like this:

def _load_jquery(self):
import os
logger.info("load jquery")

#just the location where we were storing a local copy of jQuery
#see comments below this may be better to load directly from the jQuery github page.
ROOT = os.path.dirname(file)
LIB_DIR = os.path.join(ROOT, '..', 'lib')
jquery_file = os.path.join(LIB_DIR, "jquery-latest.min.js")
jquery_lib = open(jquery_file, 'r').read()

#NOTE: I'm loading a special version of jquery that uses $j
#so basically we are changing jQuery from using $ to using $j
#browser.execute_script("var $j = jQuery.noConflict();")

browser = self._current_browser()
browser.execute_script(jquery_lib)

this is less than ideal, because it relies on a modified version of jQuery
that exists on users system. We could I guess package jQuery with S2L, but
it may be better, just to ignore (or at least document) the potential
collision issues (read, don't use with prototype.js) and then we could just
pull jQuery directly from github and thus always get the latest version.

The other thing to document / keep in mind here is that execute_script
does not honor the implicit_wait functionality built into Selenium 2. So if
you really want to do it write you should build in the implict wait
functionality into the js script that you call... i.e. put some sort of
loop / retry in the jquery.

The ultimate decision I'll leave to however implements it, cause I don't
really have time to do it at the moment.


Reply to this email directly or view it on GitHubhttps://github.com//pull/161#issuecomment-12469895.


Reply to this email directly or view it on GitHub.

@hemakannan
Copy link

Ok will keep you guys posted.
On Jan 20, 2013 9:57 AM, "Jeremy Johnson" notifications@github.com wrote:

after you have downloaded / installed the fork, you just use a locator
that starts with jquery= or sizzle= and that should trigger the query
support.

Cheers,
Jeremy

On Jan 20, 2013, at 9:54 PM, hemakannan wrote:

Yes tenwit and Jeremy
Our applications understands jquery very well that's why we have all
tests
with query selectors. Can we try to get what you have so far working and
try it at our end please.
On Jan 20, 2013 7:23 AM, "Jeremy Johnson" notifications@github.com
wrote:

Ok I had a look at the code and here is my .02.

I've written something similar and I'm about 99% sure that the
execute_script will indeed return the same thing as find_element. So I
think we are OK on that point.

And I like the fact that this is using a separate location strategy so
it
doesn't interfere will anybody who doesn't want to use it.

Now as tenwit correctly points out in his initial comment you have to
have
jQuery bundled with your application for this to work. So it doesn't
achieve the same functionality that was available in Selenium 1.

Thus since I think that is really the goal I would probably add a
check if
jQuery exists and if it doesn't exist load it. That way this
functionality
will work on pages / applications that do not have jQuery installed.
The
downside of that approach is it requires a second round trip from each
and
every call, which can really slow things down if your a using a remote
connection. Thus a different way would be to have a seperate
load_jquery
keyword that could be called one before any calls using the jQuery
location
strategy were made... of course there is an issue if the application
uses
something like prototype where you need to load jQuery with no
conflicts so
it doesn't overwrite existing frameworks. The way we got around this
in the
past was with some code like this:

def _load_jquery(self):
import os
logger.info("load jquery")

#just the location where we were storing a local copy of jQuery
#see comments below this may be better to load directly from the
jQuery github page.
ROOT = os.path.dirname(file)
LIB_DIR = os.path.join(ROOT, '..', 'lib')
jquery_file = os.path.join(LIB_DIR, "jquery-latest.min.js")
jquery_lib = open(jquery_file, 'r').read()

#NOTE: I'm loading a special version of jquery that uses $j
#so basically we are changing jQuery from using $ to using $j
#browser.execute_script("var $j = jQuery.noConflict();")

browser = self._current_browser()
browser.execute_script(jquery_lib)

this is less than ideal, because it relies on a modified version of
jQuery
that exists on users system. We could I guess package jQuery with S2L,
but
it may be better, just to ignore (or at least document) the potential
collision issues (read, don't use with prototype.js) and then we could
just
pull jQuery directly from github and thus always get the latest
version.

The other thing to document / keep in mind here is that execute_script
does not honor the implicit_wait functionality built into Selenium 2.
So if
you really want to do it write you should build in the implict wait
functionality into the js script that you call... i.e. put some sort
of
loop / retry in the jquery.

The ultimate decision I'll leave to however implements it, cause I
don't
really have time to do it at the moment.


Reply to this email directly or view it on GitHub<
https://github.com/rtomac/robotframework-selenium2library/pull/161#issuecomment-12469895>.


Reply to this email directly or view it on GitHub.


Reply to this email directly or view it on GitHubhttps://github.com//pull/161#issuecomment-12471672.

@zealic
Copy link

zealic commented Jan 29, 2013

Current version(1.1.0) not support css pseudo class "contains", +1 for jQuery locator.

@hemakannan
Copy link

Sorry guys. Been busy. I will let you guys know soon.
On Jan 29, 2013 1:09 AM, "Zealic" notifications@github.com wrote:

Current version(1.1.0) not support css pseudo class "contains", +1 for
jQuery locator.


Reply to this email directly or view it on GitHubhttps://github.com//pull/161#issuecomment-12821944.

@oforinash
Copy link

Hi Everybody my name is Gabriel and a colleague of Hema, I downloaded and installed the fork for Jquery and i'm pleased to inform you that it worked like a charm. I will like to thank you all for your support and the implementation for this added code. Our transition to webdriver will be made much easier with this addition. Hopefully this fork will be added to an official release soon.. Thank you.

@hemakannan
Copy link

Hey Guys, can this be pushed to the regular/main branch so it can be included by default in the builds we get ?

@emanlove
Copy link
Member

I think the only blocker on this was a lack of internal tests.

As for a keyword to check to see if jQuery is available this functionality request can be made in a new issue.

@tenwit
Copy link
Author

tenwit commented Mar 15, 2013

Sorry guys, completely forgot about this fork! And I've left my dev computer at work this weekend :( I'll write some tests next weekend if noone gets around to it first. I'll just find all the tests for the CSS locator and duplicate them for this one, is that about right?

Paul Hicks added 2 commits March 24, 2013 00:13
Finally back on this, sorry for the delay folks! Still teaching myself python. Duplicated the CSS table locator integration test as starting point and immediately found a bug. Fix is included: wasn't checking for jquery/sizzle prefix in table keywords.
Simple tests for jquery/sizzle locator, built from the existing links and tables tests. Includes moving the previous commit's tests to the sizzle suite, so that only one suite will fail if jquery cannot be loaded. I believe that the tests can be marked non-critical, which might be a good thing since they can fail if jquery cannot be downloaded. I'll look into this soon.
@tenwit
Copy link
Author

tenwit commented Mar 23, 2013

Right, some basic tests added. They use jQuery's own CDN to fetch jQuery, so the tests will fail if there is no internet access. I'll look into making the tests non-critical tomorrow, assuming I get time.

Suggestions on what extra tests to add will be gratefully received,

emanlove added a commit that referenced this pull request Apr 10, 2013
Add support for jQuery selectors (uses window's jQuery)
@emanlove emanlove merged commit 2d3adce into robotframework:master Apr 10, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

6 participants