Using xpath or css for Click Button

6,415 views
Skip to first unread message

N.T.

unread,
Mar 20, 2015, 5:17:38 AM3/20/15
to robotframe...@googlegroups.com
So I'm having a hard time finding the right css locator for this button, because it has no id or unique name to it. 

Here's the HTML 

<a ng-click="productAdd(productData.code, productQty, 'page')" ng-hide="(productData.unselectedMsg || cart.localMessages.itemAdd) || (cart.contents.success &amp;&amp; cart.contents.messages.itemAdd) || cart.localMessages.loading " class="button highlight">Add Item</a>

Initially I wanted to use this css path
css=a:contains("Add Item")

But it gave me this error:

InvalidSelectorException: Message: The given selector a:contains("Add Item") is either invalid or does not result in a WebElement. The following error occurred:
InvalidSelectorError: An invalid or illegal selector was specified

I tried to copy the xpath and the css to use on the Click button but I get this in the log. 

/html/body/div[3]/div[1]/div/section/div[1]/div[1]/div/div[3]/a

'xpath=/html/body/div[3]/div[1]/div/section/div[1]/div[1]/div/div[3]/a' did not match any elements.

Same with the css path I copied from the view source page. 

So am basically stuck and cannot figure out a better way to locate that button using id. 

Any suggestions?


Tatu Aalto

unread,
Mar 20, 2015, 9:47:09 AM3/20/15
to Nicole Toledo, robotframework-users

Ugh

As far I know, using CSS selector to select based on the element text is not possible [1]. But the good news is that you can do it with xpath. Example:

//a[text()="Add Item"]

Please note: The selector is untested and may contain errors.

The Firefox extensions: Firebug and Firepath are great tools to validate the selectors.

-Tatu
Send from my mobile
[1] http://www.w3.org/TR/CSS21/selector.html

--
You received this message because you are subscribed to the Google Groups "robotframework-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to robotframework-u...@googlegroups.com.
To post to this group, send email to robotframe...@googlegroups.com.
Visit this group at http://groups.google.com/group/robotframework-users.
For more options, visit https://groups.google.com/d/optout.

N.T.

unread,
Mar 20, 2015, 11:08:49 AM3/20/15
to robotframe...@googlegroups.com
Thanks!

Will try that out.

I did try using Firebug and Firepath, and that's how I got the paths placed on this post...but it didn't seem to work.

Hopefully what you said will work. Else I need to find a different workaround OR ask the devs to add an Id to the button to make it work .

N.T.

unread,
Mar 23, 2015, 1:30:08 AM3/23/15
to robotframe...@googlegroups.com
Hi 

I tried again and it didn't work.

This was the log:

20150323 14:28:15.772 :  FAIL : ValueError: Element locator 'xpath=//a[text()="Add Item"]' did not match any elements.

Did I place the xpath correctly?

Ed Manlove

unread,
Mar 23, 2015, 1:09:51 PM3/23/15
to robotframe...@googlegroups.com
Try  xpath=//a[contains(.,"Add Item")]

Note also that you will want to use the "Click Element" keyword as this is not actually a button html element but a link. (Yes you could also try 'Click Link' but I have always preferred the generic 'Click Element' keyword over any specific click * ones).

N.T. A side question for you. It looks like your application is using AngularJS, correct? I ask as I have created some locators for finding angular specific elements. If you app is testing we should talk as these might help you out some.

Ed

N.T.

unread,
Mar 24, 2015, 12:59:25 AM3/24/15
to robotframe...@googlegroups.com
Hi Ed,

Thanks. I tried out this one and it seemed to work. 

xpath=//a[contains(text(),'Add Item)]

I learned eventually that it was Click Link.

Yes we use Angular JS for our projects, and if you're okay with talking about angular js locators that would be most appreciated. 

Am now having an issue though with Clicking elements. It's weird because the element is visible and it did pass the Page Should Contain Link condition, but the logs are failing and the plugin container is failing too. I might make this a separate topic altogether though. :( 
To unsubscribe from this group and stop receiving emails from it, send an email to robotframework-users+unsub...@googlegroups.com.

Ed Manlove

unread,
Mar 24, 2015, 7:45:49 AM3/24/15
to robotframe...@googlegroups.com
When you have an issue, like this new clicking elements one, it is good to post an error message. This helps everyone understand your problem better and we can generally provide better guidance. You might also add --loglevel DEBUG to your pybot arguments to get even more information in the output.

The changes come in two branches which I have pull requests in to the rtomac repository (from which we have been using as a "master" repository). One branch is the angular changes and the other allows for using web elements in addition to a string locator.  This second change allows us to work with AngularJS repeaters.

Within the Selenium2Library changes there is a new 'Wait for Angular' Keyword, and three locator strategies "binding=", "model=", and finally "repeater=". The "repeater=" strategy can be in the form of repeater=ng repeat expression@row[index]@column=col binding where both row and column are optional. Note that returning locating just the repeat expression and/or further narrowing down to the row *OR* column will return an array of WebElement objects (thus the need for the second change noted above).

There are examples showing usage of these new AngularJS keywords in a couple of new tests,

  https://github.com/emanlove/robotframework-selenium2library/blob/angularjs/test/acceptance/locators/angular.txt
  https://github.com/emanlove/robotframework-selenium2library/blob/angularjs/test/acceptance/keywords/angular_wait.txt

To actually run these test (which it is not necessary for normal operation of Selenium2Library / Robot Framework), these tests require one to copy the test app folder, actually called testapp, from the Protractor code, 

  https://github.com/angular/protractor/tree/master/testapp

to the test/resources directory within the Selenium2Library

  https://github.com/emanlove/robotframework-selenium2library/tree/angularjs/test/resources

to run. (If you want to do that I can help you more). As mentioned these changes were in two seperate branchs and two sepearte pull requests which have not yet made it into the main repo but for convenience I have made a new branch on my fork which contains all the libraries. To use these changes you can install this modified version by follwoing these steps.

 - Download the source from my Github fork. Goto https://github.com/emanlove/robotframework-selenium2library/tree/webelement%2Bangular and on the right hand sidebar there is a link to "download zip". Click and download the source.
 - To install you can type on the command propmt   pip install webelement+angular.zip     (or the downlaoded and saved filename from step above)

This will install my modified Selenium2Library version which you can verify by typing at the command propmt    pip freeze    . In the list of install packages you should see

robotframework-selenium2library===1.7.dev-modified-angular.webelement-emanlove

which is the version I gave to this modified code (so all will know they are using a modified version). If at any point you want to revert back to the releaseed version just type

pip uninstall robotframework-selenium2library
pip install robotframework-selenium2library

If you rerun the   pip freeze   command you should see now

robotframework-selenium2library==1.6.0

There is probably more we can discuss including going through some more examples of using the new keywords and how to take advantage of them as well as some lacking capability with them but I will let you start to look around. Have a good day.

Ed
To unsubscribe from this group and stop receiving emails from it, send an email to robotframework-u...@googlegroups.com.

N.T.

unread,
Mar 26, 2015, 1:23:25 AM3/26/15
to robotframe...@googlegroups.com
Hi Ed,

First of all I apologize for not giving so much information.

So here's the issue, in case anyone gets this error again. 

After the user clicks the link "Add item" a hidden element will appear which is the link to the cart called "View Cart"

There are two keywords that are involved, which is the keyword to ADD the item to the shopping cart, and the keyword to proceed to check out with the items. 

Add item to cart
    Click Element    css=.product_listing_compact article a
    Click Element    css=.size_selector .product_size_list a:not(.unavailable)
    Click Link    xpath=//a[contains(text(),'Add Item')]
    Wait Until Page Contains Element    xpath=//a[contains(text(),'View Cart')]    30 seconds
    Comment    Page Should Contain Link    xpath=//a[contains(text(),'View Cart')]

Proceed to Checkout
    Click Element    xpath=//a[contains(text(),'View Cart')]
    Page Should Contain Element    id=cart_id
    Click Link    id=checkout_button

These keywords run in sequence, and the reason why I'm so confused is why is it that despite that the "Add Item to cart" keyword passes (since IN the log it confirms that the link is there)

So I looked again at the log: 

ElementNotVisibleException: Message: Element is not currently visible and so may not be interacted with Stacktrace: at fxdriver.preconditions.visible (file:///c:/users/t~1/appdata/local/temp/tmp4oqbvu/webdriver-py-profilecopy/extensions/fxdr...@googlecode.com/components/command-processor.js:9587) at DelayedCommand.prototype.checkPreconditions_ (file:///c:/users/t~1/appdata/local/temp/tmp4oqbvu/webdriver-py-profilecopy/extensions/fxdr...@googlecode.com/components/command-processor.js:12257) at DelayedCommand.prototype.executeInternal_/h (file:///c:/users/t~1/appdata/local/temp/tmp4oqbvu/webdriver-py-profilecopy/extensions/fxdr...@googlecode.com/components/command-processor.js:12274) at DelayedCommand.prototype.executeInternal_ (file:///c:/users/t~1/appdata/local/temp/tmp4oqbvu/webdriver-py-profilecopy/extensions/fxdr...@googlecode.com/components/command-processor.js:12279) at DelayedCommand.prototype.execute/< (file:///c:/users/t~1/appdata/local/temp/tmp4oqbvu/webdriver-py-profilecopy/extensions/fxdr...@googlecode.com/components/command-processor.js:12221)

It was JUST now that I realized that the reason why it could not be "clicked" because...it wasn't visible. I was using the WRONG keyword.

So I changed from Wait until Page Contains element to Wait Until Element is Visible. 

True enough that solved my problem. It now works.

I'm honestly not familiar with Angular JS, so I've been having so much difficulty coding my scripts. I'm saving the links you gave me for reference though. With all the angular things we have it might come in handy.

Thank you.

Ed Manlove

unread,
Mar 26, 2015, 8:26:25 PM3/26/15
to robotframe...@googlegroups.com
No problem. Just mentioned that as there are a lot of great people in the forum that can give great advice to problems. Details and error outputs help us to help you. I've too have been getting familiar with AngularJS. I am thinking that we could vreate a simple exercise/demo that follows along with the tutorial on https://docs.angularjs.org/tutorial.

Ed
To unsubscribe from this group and stop receiving emails from it, send an email to robotframework-u...@googlegroups.com.

Shailaja(Riya)

unread,
May 4, 2015, 10:09:27 AM5/4/15
to robotframe...@googlegroups.com
Please let me know , is there any documentation available for newly added keywords related with angular JS.
What exactly this keyword does " Wait For Angular" ?

Thanks,
Shailaja


On Friday, 27 March 2015 05:56:25 UTC+5:30, Ed Manlove wrote:
No problem. Just mentioned that as there are a lot of great people in the forum that can give great advice to problems. Details and error outputs help us to help you. I've too have been getting familiar with AngularJS. I am thinking that we could vreate a simple exercise/demo that follows along with the tutorial on https://docs.angularjs.org/tutorial.

Ed


On 03/26/2015 01:23 AM, N.T. wrote:
Hi Ed,

First of all I apologize for not giving so much information.

So here's the issue, in case anyone gets this error again. 

After the user clicks the link "Add item" a hidden element will appear which is the link to the cart called "View Cart"

There are two keywords that are involved, which is the keyword to ADD the item to the shopping cart, and the keyword to proceed to check out with the items. 

Add item to cart
    Click Element    css=.product_listing_compact article a
    Click Element    css=.size_selector .product_size_list a:not(.unavailable)
    Click Link    xpath=//a[contains(text(),'Add Item')]
    Wait Until Page Contains Element    xpath=//a[contains(text(),'View Cart')]    30 seconds
    Comment    Page Should Contain Link    xpath=//a[contains(text(),'View Cart')]

Proceed to Checkout
    Click Element    xpath=//a[contains(text(),'View Cart')]
    Page Should Contain Element    id=cart_id
    Click Link    id=checkout_button

These keywords run in sequence, and the reason why I'm so confused is why is it that despite that the "Add Item to cart" keyword passes (since IN the log it confirms that the link is there)

So I looked again at the log: 

ElementNotVisibleException: Message: Element is not currently visible and so may not be interacted with Stacktrace: at fxdriver.preconditions.visible (file:///c:/users/t~1/appdata/local/temp/tmp4oqbvu/webdriver-py-profilecopy/extensions/fxdriver@googlecode.com/components/command-processor.js:9587) at DelayedCommand.prototype.checkPreconditions_ (file:///c:/users/t~1/appdata/local/temp/tmp4oqbvu/webdriver-py-profilecopy/extensions/fxdriver@googlecode.com/components/command-processor.js:12257) at DelayedCommand.prototype.executeInternal_/h (file:///c:/users/t~1/appdata/local/temp/tmp4oqbvu/webdriver-py-profilecopy/extensions/fxdriver@googlecode.com/components/command-processor.js:12274) at DelayedCommand.prototype.executeInternal_ (file:///c:/users/t~1/appdata/local/temp/tmp4oqbvu/webdriver-py-profilecopy/extensions/fxdriver@googlecode.com/components/command-processor.js:12279) at DelayedCommand.prototype.execute/< (file:///c:/users/t~1/appdata/local/temp/tmp4oqbvu/webdriver-py-profilecopy/extensions/fxdriver@googlecode.com/components/command-processor.js:12221)

Phuoc Ha

unread,
May 5, 2015, 3:08:41 AM5/5/15
to robotframe...@googlegroups.com
You should use the simple way

Click Link        link=Add Item

Vào 16:17:38 UTC+7 Thứ Sáu, ngày 20 tháng 3 năm 2015, N.T. đã viết:

Trent Himes

unread,
May 6, 2015, 3:15:26 PM5/6/15
to robotframe...@googlegroups.com
Don't you have to use the word 'sizzle'? As in: sizzle=a:contains("Add Item")

That's what I do an it always works.

N.T.

unread,
May 26, 2015, 1:19:35 AM5/26/15
to robotframe...@googlegroups.com
Can that work for Robot Framework though? I've seen in Selenium Libraries to always use an xpath or ID. 
Reply all
Reply to author
Forward
0 new messages