Skip to content
This repository was archived by the owner on Feb 2, 2025. It is now read-only.

updated the following keywords so they correctly handle case sensitiv… #76

Merged
merged 1 commit into from
Jul 16, 2019
Merged

Conversation

ractoc
Copy link
Contributor

@ractoc ractoc commented Jul 11, 2019

Conform Issue #75 I have prepared this pull request.

updated the following keywords so they correctly handle case sensitivity conform the Python implementation

Element Should Contain
Element Should Not Contain
Element Text Should Be
Element Text Should Not Be

public void elementShouldContain(String locator, String text, String...params) {
String message = robot.getParamsValue(params, 0, "");
String message = robot.getParamsValue(params, 0, "");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we use StringUtils from commons-lang3, perhaps, we can use EMPTY instead of "" here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea.

if (text.equals(actual)) {
if (message == null || message.equals("")) {
if (textToCompare.equals(actual)) {
if (StringUtils.isNotBlank(message)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically, this looks like a backward incompatible change because isNotBlank isn't the same as isNotEmpty.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with using isNotEmpty instead.

String textToCompare = text;
if (ignoreCase) {
actual = actual.toLowerCase();
textToCompare = textToCompare.toLowerCase();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kep that toLower from the original code of the class. So I'm fine with any way you want to change that. The main thing that needed adding was the option to chooise between testing with and without case sensitivity.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm changing it to:

String actual = elements.get(0).getText();
if (!(ignoreCase && text.equalsIgnoreCase(actual)) || !(!ignoreCase && text.equals(actual))) {
}

String textToCompare = text;
if (ignoreCase) {
actual = actual.toLowerCase();
textToCompare = textToCompare.toLowerCase();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using toLowerCase()/toUpperCase() without specifying a locale leads to bugs like that: https://garygregory.wordpress.com/2015/11/03/java-lowercase-conversion-turkey/

:-/

@ractoc
Copy link
Contributor Author

ractoc commented Jul 11, 2019

I'll check if I can implement the relevant changes you suggested above later today. More meetings first...

@ractoc
Copy link
Contributor Author

ractoc commented Jul 11, 2019

@php-coder I think I got all of the issues sorted.

String actual = getText(locator);

if (!actual.toLowerCase().contains(text.toLowerCase())) {
if ((!(ignoreCase && StringUtils.containsIgnoreCase(actual, text))) || !(!ignoreCase && StringUtils.contains(actual, text))) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better for readability if we extract all these logical operations into a variable? Something like this:

boolean contains = ignoreCase
    ? StringUtils.containsIgnoreCase(actual, text)
    : StringUtils.contains(actual, text);

if we can't use ternary operation and you think that it's not readable, here is the option with simple if:

boolean contains = false;
if (ignoreCase) {
    contains = StringUtils.containsIgnoreCase(actual, text);
} else {
    contains = StringUtils.contains(actual, text);
}

WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, I think the terniary operation should work.
Give me 15 minutes...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And pushed...

@ractoc
Copy link
Contributor Author

ractoc commented Jul 11, 2019

I'm heading home now, I'll look into it more tomorrow if there are more findings

String actual = getText(locator);

if (actual.toLowerCase().contains(text.toLowerCase())) {
if (!textContains(actual, text, ignoreCase)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like copy&paste mistake -- textContains() should be here.

@@ -1096,4 +1103,16 @@ public static String escapeXpathValue(String value) {
return String.format("'%s'", value);
}

private boolean textContains(String actual, String text, boolean ignoreCase) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is even better 👍

One tiny idea: how about adding static modifier to these utility methods?

@Hi-Fi
Copy link
Collaborator

Hi-Fi commented Jul 11, 2019

First of all thank you for the PR.

I think getText can return null, so there might be extra NPEs coming from (original) code, too. If those could be checked at the same time it would be nice. I think most of those would be bypassed by using StringUtils -methods instead of String's own ones.

@ractoc
Copy link
Contributor Author

ractoc commented Jul 12, 2019

I did a quick check of the StringUtils methods. If either actual or text is null, those methods return false. So that should work nicely

return ignoreCase
? StringUtils.containsIgnoreCase(actual, text)
: StringUtils.contains(actual, text);
}

private boolean textIs(String actual, String text, boolean ignoreCase) {
public static boolean textIs(String actual, String text, boolean ignoreCase) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like indentation here is incorrect.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed te indentation. For some reason, this one was using tabs instead of spaces. the other indentations all worked with tabs...

@@ -1103,13 +1103,13 @@ public static String escapeXpathValue(String value) {
return String.format("'%s'", value);
}

private boolean textContains(String actual, String text, boolean ignoreCase) {
public static boolean textContains(String actual, String text, boolean ignoreCase) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally don't see a reason to declare these methods as public but it shouldn't hurt.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

without making them public, making them static doesn't really make a lot of sense, since they are never called from a static method within the class itself

Copy link

@php-coder php-coder Jul 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I agree that there is no "a lot of sense" and this topic is... debatable. From my point of view, "private static" is still make sense because

  1. it emphasizes the fact that this method doesn't depend on other class members (doesn't use internal state)
  2. JVM doesn't pass this as the first parameter to such the methods

Here are my points. The last call, of course, in on @Hi-Fi and you :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm doing one more commit. Do I leave this in as public static, or revert it back to private?
private static doesn't make much sense since in the class it is never called from a static context.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For me both are ok. Maybe original is better if there's no clear reason for change.

@ractoc
Copy link
Contributor Author

ractoc commented Jul 12, 2019

final commit, I hope...

@@ -25,1075 +26,1093 @@
@RobotKeywords
public class Element extends RunOnFailureKeywordsAdapter {

/**

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:-( That's a little unexpected that now nearly all the lines were modified..

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, now I see
yes, I converted tabs to spaces, thinking my line was the only line with this problem.
Since this is just about the only change in this commit, it shouldn't be too bad though

@php-coder
Copy link

@ractoc Thank you, Mark!

If you aren't fully tired with that, you might want to squash 5 commits into single one (see https://davidwalsh.name/squash-commits-git).

…tShouldBe and elementText ShouldNotBe to support either case sensitive or case insensitive operation. This is in line with recent changes to the Python version of the selenium library.

Unfortunately, along the way, the indentation has been changed from tabs to all spaces.
@ractoc
Copy link
Contributor Author

ractoc commented Jul 15, 2019

That should do it then...
Now, if you set the compare to ignore whitespace changes, you should get only the actual changes

@Hi-Fi Hi-Fi merged commit 637fb35 into MarketSquare:develop Jul 16, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants