Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add parameter to make Wait Until Page Contains case insensitive #1517

Open
apuchkov opened this issue Nov 19, 2019 · 12 comments
Open

Add parameter to make Wait Until Page Contains case insensitive #1517

apuchkov opened this issue Nov 19, 2019 · 12 comments

Comments

@apuchkov
Copy link

It would be great to be able to turn off case sensitivity for keywords like Element Text Should Be, Wait Until Element Contains, Wait Until Element Does Not Contain, Wait Until Page Contains and Wait Until Page Does Not Contain

This feature was already implemented for Element Should Contain and Element Should Not Contain in #849.

I spent lots of time trying to understand why Wait Until Page Contains fails just to find that it is a case sensitive and case on the screen was displayed differently, because of CSS style: text-transform: lowercase

I would vote to make these keywords case insensitive by default and case sensitive via parameter. I think it would make tests faster to write and less brittle.

@aaltat
Copy link
Contributor

aaltat commented Nov 19, 2019

For all the keywords that verifies text from from a single element, adding the case insensitive argument sounds like good idea. Also they should not be complicated to do. But the Page Should (Not) Contain keywords are problematic, because they use xpath internally to find the text from the page. And if I recall correctly, xpath doesn't support this type of conversions. But there might be other solutions available and investigation is a good idea.

Do you have @apuchkov have an interest to provide a PR for this enhancement request?

@pekkaklarck
Copy link
Member

👍 for this in general but 👎 for making case-insensitivity the default.

@aaltat
Copy link
Contributor

aaltat commented Nov 19, 2019

I agree that keywords should stay case sensitive by default.

@ritikasaboo
Copy link

Since Page Should (Not) Contain depends internally on is_text_present (xpath expression: "xpath://*[contains(., %s)]" % escape_xpath_value(text)), is it possible to alter that function to add case insensitivity and then perform a similar solution as:

https://stackoverflow.com/questions/2893551/case-insensitive-matching-in-xpath OR
https://stackoverflow.com/questions/8474031/case-insensitive-xpath-contains-possible

What would be the pitfalls of this? I'm new to open source and would love to contribute in any way I can. Hope this wasn't too silly a question.

@aaltat
Copy link
Contributor

aaltat commented Dec 6, 2019

Last time I did check, browsers did not support xpath 2. But that was pretty long time ago, so things might have changed. But it can be easily tested by using browser developer tools.

But if you find out a combination which works with as many browsers as possible, we can make the xpath configurable. You don't need SeleniumLibrary to test it, just use different browsers developer tools. If you happen to find a good combination (good means that works as many browser as possible), we can talk more.

@ritikasaboo
Copy link

ritikasaboo commented Dec 8, 2019

Yes, upper & lower case functions are part of Xpath 2.0

However, there is a workaround that works for Xpath 1.0:

//*[
  contains(
    translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),
    'test'
  )
]

I've checked this for Chrome & Firefox using developer tools, and I am able to find text via xpath case insensitively. I think this should also work for Edge/IE; will confirm on that soon.

How do you want to proceed? I'd love to contribute on this. Thanks!

@aaltat
Copy link
Contributor

aaltat commented Dec 8, 2019

Does work with characters outside of the ASCII range, example with utf-8 and utf-16?

Those xpath2 functions would be good solution, did you check does the browser support them nowdays?

@ritikasaboo
Copy link

ritikasaboo commented Dec 9, 2019

Here's a sample example I ran to check a non-ASCII character:

`<html>
<head></head><body>
<p title="empire"> teXTĀ </p>
<p title="Empire"> TeXTĀ </p>
<p title="EMpire"> textĀ </p>
<p title="EMPire"> texTā </p>
</body></html>
`

xpath 1.0 expression: //p[contains(translate(.,"TEXTĀ","textā"), "textā")]

This actually identifies all 4 p-tags, which leads me to believe that the translate() function supports ASCII and non-ASCII characters.

As for Xpath 2.0, I believe it is not supported by browsers still. Search results from a couple of years ago suggest that there's no future plans to support Xpath 2.0 by browsers. Additionally, running //p[lower-case(@title)='empire'] against above web page gives no results in Chrome, which probably confirms that Xpath 2.0 is NOT supported.

Is it possible to perform string manipulation on the search text in python and then search via xpath, which means we may not need case-insensitive xpath solutions in the first place? Let me know how you want to proceed.

@aaltat
Copy link
Contributor

aaltat commented Dec 9, 2019

Well, almost everything is possible in the Python side, keyword could construct the translated text inside of the keyword. Most likely Python upper() and lower() should work pretty well. Needs testing with all kinds of funny characters and therefore looking example big list of naughty strings might be useful. SeleniumLibrary has subset of blns in use.

@ritikasaboo
Copy link

ritikasaboo commented Dec 9, 2019

Do you want to use the xpath translate() solution or the Python string manipulation approach? How do you want me to proceed with providing an acceptable solution? Could you guide me through this process, if you can afford the time? I'd like contribute to this issue. Thanks, let me know.

I could perform string manipulation on the search text but it would have to cover all possibilities of case-insensitivity on the page.
I think the xpath solution is the way to go? A

@aaltat
Copy link
Contributor

aaltat commented Dec 9, 2019

Well, there are two factors to take in account.

  1. For the keywords that deal with element, like Wait Until Element Contains, it is easier to do conversion in Python side. For those keywords one can copy the implementation from Element Should Contain and Element Should Not Containkeywords.
  2. The Page Should (Not) Contain keywords needs research is it possible to implement ignore_case argument. So far I can think several possibilities how it can be done, but all of them requires research. Also without doing or reading the implementation, it is impossible to say which way I would prefer. Because there are always so many things to learn during the implementation, which may lead to the implementation to totally new areas. But generally code should follow the coding conventions set to the project.

For me it is always easiest to do TDD when writing implementation for any thing.

@ritikasaboo
Copy link

I believe keywords such as Wait Until Element Contains already have a case-insensitive implementation that involve conversion on the Python side.

With regards to utf-8/utf-16/blns-- how exactly do you want me to map case-wise? I would need a comprehensive list of characters with case mappings to ensure the xpath translate() function covers non-ASCII. If I have this, I can attempt one kind of solution for starters and we can explore post that implementation. Please let me know/guide me on this.

So far I can think several possibilities how it can be done, but all of them requires research.

What other possible implementations come to mind? I don't think the implementation applied to Element Should Contain can be rehashed for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants