You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I would like to have another locator strategy added, tentatively named "label". This would look for a label element with the given text, then return the element pointed to by the "for" attribute of that label element.
Rationale:
Django (and other frameworks?) create forms that look like this:
<label for="id_some_form_field">I accept the terms</label>
<input id='id_some_form_field' type='checkbox'>
I would like to interact with the form field by specifying the label rather than having to use some other locator. For example, to validate that this checkbox is checked I want to do something like this:
click element label=I accept the terms
checkbox should be selected label=I accept the terms
I think this would make it easier for people who didn't write the code be able to write tests, because they wouldn't have to know the underlying element IDs; instead, they can simply enter in what they see on the screen.
Further, I recommend we support the stripping of leading and trailing spaces and dots to allow for a simple type of pattern matching. Say, for example, you have a form field that has the label "I have read the terms of service and agree to be bound by them". It would be cumbersome to type all of that into a test case, so it would be nice to support something like this:
checkbox should be selected label=I have read the terms of service...
I am willing to write the implementation. This issue is for generating discussion, and to see if this would be a generally useful locator strategy.
Yes, I know you can add a custom location strategy. I'm doing this now. I
think it is a generally useful location strategy which is why I'm
suggesting it be included in the core set of location strategies.
Although @boakley idea is good one and perhaps we should do it, I feel that doing this with xpath is more flexible and better. Also because many web development frameworks do produce very different kind of DOM trees, for same kind of looking elements, nailing this one down could be really difficult.
In @boakley case perhaps I would do it like this: xpath=//label[[starts-with(.,'${text}')]/input and I would create general keyword which would click/select/or what ever it should be doing, so that it can be used anywhere the general activity is created.
To me the hard part, which I think would need to be discussed and debated, is exactly how one specifies either full text or partial text. Does/Can one use regular expression? Can one use eclipses (...)? How else would someone want to specify the search text? This is important as once implemented it will be hard to change.
@boakley Do you see a need beyond what @aaltat suggests using xpath? Is this more of a problem of education where we need to better help users use locators?
The input element isn't necessarily immediately following the label, so
your xpath can't work in a general sense. Plus, the whole point is to ask
the label for the input element it belongs to.
Although @boakleyhttps://github.com/boakley idea is good one and
perhaps we should do it, I feel that doing this with xpath is more flexible
and better. Also because many web development frameworks do produce very
different kind of DOM trees, for same kind of looking elements, nailing
this one down could be really difficult.
In @boakleyhttps://github.com/boakley case perhaps I would do it like
this: xpath=//label[[starts-with(.,'${text}')]/input and I would create
general keyword which would click/select/or what ever it should be doing,
so that it can be used anywhere the general activity is created.
To me the hard part, which I think would need to be discussed and debated,
is exactly how one specifies either full text or partial text. Does/Can one
use regular expression?
What I do now is strip of leading and trailing spaces and dots, and then
search for a label that contains the text. It works quite well.
The input element isn't necessarily immediately following the label, so
your xpath can't work in a general sense. Plus, the whole point is to ask
the label for the input element it belongs to.
Although @boakleyhttps://github.com/boakley idea is good one and
perhaps we should do it, I feel that doing this with xpath is more flexible
and better. Also because many web development frameworks do produce very
different kind of DOM trees, for same kind of looking elements, nailing
this one down could be really difficult.
In @boakleyhttps://github.com/boakley case perhaps I would do it like
this: xpath=//label[[starts-with(.,'${text}')]/input and I would create
general keyword which would click/select/or what ever it should be doing,
so that it can be used anywhere the general activity is created.
Agreed and I like the simply solution. But the question arises what other needs/requirements could one have? And if such needs arise would they be backward compatible? How could we accommodate them to perform the same action, find the element with the associated label, with a more complex need?
Could you share the code? I don't quite understand, how finding the label
helps one to click the check box. Unless the label is listening the click
event and is able to check the check box (which of course is good
implementation but don't work with all cases).
Also xpath has contains and normalise-space, which could be also useful.
-Tatu
Send from my mobile
On 14 Nov 2015 3:51 p.m., "Bryan Oakley" notifications@github.com wrote:
To me the hard part, which I think would need to be discussed and
debated,
is exactly how one specifies either full text or partial text. Does/Can
one
use regular expression?
What I do now is strip of leading and trailing spaces and dots, and then
search for a label that contains the text. It works quite well.
The input element isn't necessarily immediately following the label, so
your xpath can't work in a general sense. Plus, the whole point is to ask
the label for the input element it belongs to.
Although @boakleyhttps://github.com/boakley idea is good one and
perhaps we should do it, I feel that doing this with xpath is more
flexible
and better. Also because many web development frameworks do produce very
different kind of DOM trees, for same kind of looking elements, nailing
this one down could be really difficult.
In @boakleyhttps://github.com/boakley case perhaps I would do it
like
this: xpath=//label[[starts-with(.,'${text}')]/input and I would create
general keyword which would click/select/or what ever it should be
doing,
so that it can be used anywhere the general activity is created.
Could you share the code? I don't quite understand, how finding the label
helps one to click the check box. Unless the label is listening the click
event and is able to check the check box (which of course is good
implementation but don't work with all cases).
You don't click on the label. You use xpath to get the "for" attribute of
the label. This will return an element id of a form element. You then click
on that id. So, assuming you have something like "Username", a locator of "label=Username" is
identical to the locator "id=id_username".
The benefit is that with "label=" you don't have to know the id of the form
element. All you need is to look at the web page and use the label.
Assuming the label doesn't change, the underlying id can change without
having to modify the test. This happens a lot with systems that
auto-generate ids.
Could you share the code? I don't quite understand, how finding the label
helps one to click the check box. Unless the label is listening the click
event and is able to check the check box (which of course is good
implementation but don't work with all cases).
Also xpath has contains and normalise-space, which could be also useful.
-Tatu
Send from my mobile
On 14 Nov 2015 3:51 p.m., "Bryan Oakley" notifications@github.com wrote:
To me the hard part, which I think would need to be discussed and
debated,
is exactly how one specifies either full text or partial text. Does/Can
one
use regular expression?
What I do now is strip of leading and trailing spaces and dots, and then
search for a label that contains the text. It works quite well.
The input element isn't necessarily immediately following the label, so
your xpath can't work in a general sense. Plus, the whole point is to
ask
the label for the input element it belongs to.
Although @boakleyhttps://github.com/boakley idea is good one and
perhaps we should do it, I feel that doing this with xpath is more
flexible
and better. Also because many web development frameworks do produce
very
different kind of DOM trees, for same kind of looking elements,
nailing
this one down could be really difficult.
In @boakleyhttps://github.com/boakley case perhaps I would do it
like
this: xpath=//label[[starts-with(.,'${text}')]/input and I would
create
general keyword which would click/select/or what ever it should be
doing,
so that it can be used anywhere the general activity is created.
—
Reply to this email directly or view it on GitHub
<
Ah, I think I understand what you do in our keyword and if the Django framework does it like that, I understand your reasoning behind keyword logic. In practice you want to find label element, get the id of the label and then find input, or some other element based based on the id of the label element. All the other web app frameworks, which I have say that can be counted with one hand fingers, do not do it like the Djongo does it. If you want to hide the complexity of selecting elements, I am not sure is Selenium2Library a correct level for it. I am not sure will it be possible to make general keyword that would fit to the need described in the above. But I am not against to create a label strategy for selecting elements, but I think the label strategy should only match to the <label for='id_username'>Username</label> element and nothing more.
But I can understand your need and basically, I am facing similar situation in my work place. I need to raise the abstraction level so that the keywords are easier to use for people that do not actively work with seleniun(2library) and/or understand the xpath that well. Also there is lot of shared resources, example for table keywords and also other stuff. It has come quite nightmare to handle all the inheritance in the Robot Framework data and therefore we have decided to move to a page object model and it is done in Python. This allows us to provide better and clearer interface, handle inheritance better and get the all the benefits of using real programming language.
We use and will use Selenium2Library in the future but we are going to the same direction, which the Page Object Library did try to do. We have just started of doing this and but it looks really good and for now, I only regret that we did not start it sooner.
You use xpath to get the "for" attribute of the label. This will return an element id of a form element.
Don't forget that the "for" attribute is not necessary. One can also wrap the input element with the associated label (as per spec: HTML4, HTML5). So the implementation of this keyword should handle this allowance by the specification.
We use and will use Selenium2Library in the future but we are going to the
same direction, which the Page Object Library https://github.com/ncbi/robotframework-pageobjects did try to do. We
have just started of doing this and but it looks really good and for now, I
only regret that we did not start it sooner.
I completely agree. I first used page objects seriously at my previous job,
and it helped make our tests more stable. At my current job I wrote my own
page object implementation and we're having absolutely fantastic success.
This really is the better approach -- embed all of the page knowledge in
python code so that the test can focus on test logic. We still leverage
Selenium2Library within in the page object implementation, however.
That's how this feature request came to be. I had implemented my own
locator strategy for labels to deal with all of the checkboxes that our
site uses. I thought this could be more generally useful if it was part of
Selenium2Library rather than a feature of our custom page objects.
Ah, I think I understand what you do in our keyword and if the Django
framework does it like that, I understand your reasoning behind keyword
logic. In practice you want to find label element, get the id of the label
and then find input, or some other element based based on the id of the
label element. All the other web app frameworks, which I have say that can
be counted with one hand fingers, do not do it like the Djongo does it. If
you want to hide the complexity of selecting elements, I am not sure is
Selenium2Library a correct level for it. I am not sure will it be possible
to make general keyword that would fit to the need described in the above.
But I am not against to create a label strategy for selecting elements, but
I think the label strategy should only match to the Username element and nothing more.
But I can understand your need and basically, I am facing similar
situation in my work place, I need to raise the abstraction level so that
the keywords are easier to use for people that do not actively work with
seleniun(2library) and/or understand the xpath that well. Also there is lot
of shared resources, example for table keywords and also other stuff. It
has come quite nightmare to handle all the inheritance in the Robot
Framework data and therefore we have decided to move to a page object model
and it is done in Python. This allows us to provide better and clearer
interface, handle inheritance better and get the all the benefits of using
real programming language.
We use and will use Selenium2Library in the future but we are going to the
same direction, which the Page Object Library https://github.com/ncbi/robotframework-pageobjects did try to do. We
have just started of doing this and but it looks really good and for now, I
only regret that we did not start it sooner.
A more generic approach would be using nested locators. Like label=xpath=//label[., starts-with('Blah')]. This way the label could be located however desired. The label strategy could have key attributes like id or text so that label=Blah would search by id or text "Blah" since a second locator prefix was not used. This is just brainstorming. With nested locator prefixes, the prefix with label makes more sense e.g. "with label=id=label_123"
A more generic approach would be using nested locators. Like
label=xpath=//label[., starts-with('Blah')]
No, not really. That solves a completely different problem. This proposal
specifically is to address the case where you have a label element with a
"for" attribute that points to the form element that the label is for. The
label and the input element could each be anywhere in the DOM.
A more generic approach would be using nested locators. Like
label=xpath=//label[., starts-with('Blah')]. This way the label could be
located however desired. The label strategy could have key attributes like
id or text so that label=Blah would search by id or text "Blah" since a
second locator prefix was not used. This is just brainstorming. With nested
locator prefixes, the prefix with label makes more sense e.g. "with
label=id=label_123"
I don't know what I want to do. I'm a bit surprised at how confusing this
request has been to the few people who have responded. I don't want to add
something that will confuse people.
I've been sitting back, hoping more people would join the discussion. I
guess if there's very little interest I'll probably withdraw the request.
Perhaps there aren't very many people using robot with django...?
@boakley I think I understand the problem. My suggestion of nested locators was to address @emanlove's concern about partial text, full text, regular expression, etc. If you have the full power of a locator than you can handle locating the label element in any way you want (except for regex). The final element located would always be the element the label is for, regardless of location in DOM. Your use case of matching full label text is pretty narrow, and I'm just thinking of the long run.
There has not been activity for this issue for long time and we are planning to close the old issues if they are not anymore valid ones. If you feel that this is still valid issue, could you send an update. If update is not received in a month, we will assume that this is not anymore an issues and we will close this issue.
@aaltat with @HelioGuilherme66 and another user in the slack channel , the need of a "Click Element Where Text Is" raised again. Due a solution can be the use of a xpath, maybe we can add this example in the documentation of Click Element with xpath locator?
Searching "by label" is not same as searching "by text". When searching by label you'd find first a label element and based on it then the actual element. Then searching by text, you find the element directly based on its text content.
I'd be fine adding built-in support for both labels and text, but they both require someone to need them badly enough to provide a PR. Adding a new example to documentation is a good idea too. Please submit a new issue and/or PR!
Hi All, I too came here looking for this very feature. I wish there was a label-based input selector out of the box, and I don't think this is by any means a Django-specific issue. I want to use it specifically with for="some-id" but agree that the wrapped variation would be useful as well.
Activity
just-be-dev commentedon Nov 13, 2015
Maybe it isn't documented well enough, but you can add a custom location strategy. Here's the acceptance test for it: https://github.com/robotframework/Selenium2Library/blob/master/test/acceptance/locators/custom.robot
boakley commentedon Nov 13, 2015
Yes, I know you can add a custom location strategy. I'm doing this now. I
think it is a generally useful location strategy which is why I'm
suggesting it be included in the core set of location strategies.
On Fri, Nov 13, 2015 at 3:59 PM, Zephraph notifications@github.com wrote:
aaltat commentedon Nov 14, 2015
Although @boakley idea is good one and perhaps we should do it, I feel that doing this with xpath is more flexible and better. Also because many web development frameworks do produce very different kind of DOM trees, for same kind of looking elements, nailing this one down could be really difficult.
In @boakley case perhaps I would do it like this:
xpath=//label[[starts-with(.,'${text}')]/inputand I would create general keyword which would click/select/or what ever it should be doing, so that it can be used anywhere the general activity is created.emanlove commentedon Nov 14, 2015
To me the hard part, which I think would need to be discussed and debated, is exactly how one specifies either full text or partial text. Does/Can one use regular expression? Can one use eclipses (...)? How else would someone want to specify the search text? This is important as once implemented it will be hard to change.
@boakley Do you see a need beyond what @aaltat suggests using xpath? Is this more of a problem of education where we need to better help users use locators?
boakley commentedon Nov 14, 2015
The input element isn't necessarily immediately following the label, so
your xpath can't work in a general sense. Plus, the whole point is to ask
the label for the input element it belongs to.
On Sat, Nov 14, 2015 at 7:11 AM, Tatu Aalto notifications@github.com
wrote:
boakley commentedon Nov 14, 2015
What I do now is strip of leading and trailing spaces and dots, and then
search for a label that contains the text. It works quite well.
On Sat, Nov 14, 2015 at 7:49 AM, Bryan Oakley bryan.oakley@gmail.com
wrote:
emanlove commentedon Nov 14, 2015
Agreed and I like the simply solution. But the question arises what other needs/requirements could one have? And if such needs arise would they be backward compatible? How could we accommodate them to perform the same action, find the element with the associated label, with a more complex need?
aaltat commentedon Nov 14, 2015
Ugh
Could you share the code? I don't quite understand, how finding the label
helps one to click the check box. Unless the label is listening the click
event and is able to check the check box (which of course is good
implementation but don't work with all cases).
Also xpath has contains and normalise-space, which could be also useful.
-Tatu
Send from my mobile
On 14 Nov 2015 3:51 p.m., "Bryan Oakley" notifications@github.com wrote:
boakley commentedon Nov 14, 2015
You don't click on the label. You use xpath to get the "for" attribute of
the label. This will return an element id of a form element. You then click
on that id. So, assuming you have something like "Username", a locator of "label=Username" is
identical to the locator "id=id_username".
The benefit is that with "label=" you don't have to know the id of the form
element. All you need is to look at the web page and use the label.
Assuming the label doesn't change, the underlying id can change without
having to modify the test. This happens a lot with systems that
auto-generate ids.
On Sat, Nov 14, 2015 at 10:03 AM, Tatu Aalto notifications@github.com
wrote:
aaltat commentedon Nov 14, 2015
Ah, I think I understand what you do in our keyword and if the Django framework does it like that, I understand your reasoning behind keyword logic. In practice you want to find label element, get the id of the label and then find input, or some other element based based on the id of the label element. All the other web app frameworks, which I have say that can be counted with one hand fingers, do not do it like the Djongo does it. If you want to hide the complexity of selecting elements, I am not sure is Selenium2Library a correct level for it. I am not sure will it be possible to make general keyword that would fit to the need described in the above. But I am not against to create a label strategy for selecting elements, but I think the label strategy should only match to the
<label for='id_username'>Username</label>element and nothing more.But I can understand your need and basically, I am facing similar situation in my work place. I need to raise the abstraction level so that the keywords are easier to use for people that do not actively work with seleniun(2library) and/or understand the xpath that well. Also there is lot of shared resources, example for table keywords and also other stuff. It has come quite nightmare to handle all the inheritance in the Robot Framework data and therefore we have decided to move to a page object model and it is done in Python. This allows us to provide better and clearer interface, handle inheritance better and get the all the benefits of using real programming language.
We use and will use Selenium2Library in the future but we are going to the same direction, which the Page Object Library did try to do. We have just started of doing this and but it looks really good and for now, I only regret that we did not start it sooner.
emanlove commentedon Nov 15, 2015
Don't forget that the "for" attribute is not necessary. One can also wrap the input element with the associated label (as per spec: HTML4, HTML5). So the implementation of this keyword should handle this allowance by the specification.
boakley commentedon Nov 15, 2015
I completely agree. I first used page objects seriously at my previous job,
and it helped make our tests more stable. At my current job I wrote my own
page object implementation and we're having absolutely fantastic success.
This really is the better approach -- embed all of the page knowledge in
python code so that the test can focus on test logic. We still leverage
Selenium2Library within in the page object implementation, however.
That's how this feature request came to be. I had implemented my own
locator strategy for labels to deal with all of the checkboxes that our
site uses. I thought this could be more generally useful if it was part of
Selenium2Library rather than a feature of our custom page objects.
On Sat, Nov 14, 2015 at 1:07 PM, Tatu Aalto notifications@github.com
wrote:
aaltat commentedon Nov 23, 2015
@boakley What you want to do with this issue? And what do others think?
ombre42 commentedon Nov 23, 2015
A more generic approach would be using nested locators. Like label=xpath=//label[., starts-with('Blah')]. This way the label could be located however desired. The label strategy could have key attributes like id or text so that label=Blah would search by id or text "Blah" since a second locator prefix was not used. This is just brainstorming. With nested locator prefixes, the prefix with label makes more sense e.g. "with label=id=label_123"
divfor commentedon Nov 25, 2015
here is an example to use 'Add Location Strategy' for this:
define.txt:
boakley commentedon Nov 25, 2015
No, not really. That solves a completely different problem. This proposal
specifically is to address the case where you have a label element with a
"for" attribute that points to the form element that the label is for. The
label and the input element could each be anywhere in the DOM.
On Mon, Nov 23, 2015 at 10:53 AM, Kevin Ormbrek notifications@github.com
wrote:
boakley commentedon Nov 25, 2015
Sorry I didn't respond earlier.
I don't know what I want to do. I'm a bit surprised at how confusing this
request has been to the few people who have responded. I don't want to add
something that will confuse people.
I've been sitting back, hoping more people would join the discussion. I
guess if there's very little interest I'll probably withdraw the request.
Perhaps there aren't very many people using robot with django...?
On Mon, Nov 23, 2015 at 10:01 AM, Tatu Aalto notifications@github.com
wrote:
aaltat commentedon Nov 25, 2015
Not many people actively follow issue tracker, perhaps it would be good idea to advertise the problem in the user group and in the slack channel?
ombre42 commentedon Nov 25, 2015
@boakley I think I understand the problem. My suggestion of nested locators was to address @emanlove's concern about partial text, full text, regular expression, etc. If you have the full power of a locator than you can handle locating the label element in any way you want (except for regex). The final element located would always be the element the label is for, regardless of location in DOM. Your use case of matching full label text is pretty narrow, and I'm just thinking of the long run.
pekkaklarck commentedon Nov 25, 2015
FWIW, I think that
forand labels wrapping the element should be supportedlabel=My label)label=id=example)aaltat commentedon May 23, 2016
There has not been activity for this issue for long time and we are planning to close the old issues if they are not anymore valid ones. If you feel that this is still valid issue, could you send an update. If update is not received in a month, we will assume that this is not anymore an issues and we will close this issue.
andreabisello commentedon Nov 16, 2016
@aaltat in my web application i often use as "button" but i have any locator to find a label.
now i'm using, as a workaround, this finder
Click Element xpath=//*[contains(text(),'ABC')]
but i think a
Click Element label=ABC
that will click element with label - span containing ABC will be usefull.
andreabisello commentedon Oct 2, 2017
@aaltat with @HelioGuilherme66 and another user in the slack channel , the need of a "Click Element Where Text Is" raised again. Due a solution can be the use of a xpath, maybe we can add this example in the documentation of Click Element with xpath locator?
pekkaklarck commentedon Oct 2, 2017
Searching "by label" is not same as searching "by text". When searching by label you'd find first a label element and based on it then the actual element. Then searching by text, you find the element directly based on its text content.
I'd be fine adding built-in support for both labels and text, but they both require someone to need them badly enough to provide a PR. Adding a new example to documentation is a good idea too. Please submit a new issue and/or PR!
jruuttun commentedon Jan 4, 2019
Hi All, I too came here looking for this very feature. I wish there was a label-based input selector out of the box, and I don't think this is by any means a Django-specific issue. I want to use it specifically with
for="some-id"but agree that the wrapped variation would be useful as well.aaltat commentedon Jan 4, 2019
It is true that it would be useful, but @pekkaklarck comment from the above still holds water very well.