What is the meaning of the word "visible" in the "given web element is visible within timeout." in Katalon?

What is the meaning of the word “visible” in the “given web element is visible within timeout.” in Katalon?

Does it mean that the element is potentially visible (e.g the element can be made visible if you scroll to it, but you might not see it w/o scrolling)?

Does it mean that the element is actually visible (i.e. you can see the element w/o any scrolling )?

https://docs.katalon.com/javadoc/index.html

@CompileStatic @Keyword(keywordObject = StringConstants.KW_CATEGORIZE_ELEMENT) static boolean waitForElementVisible (TestObject to, int timeOut)

Wait until the given web element is visible within timeout.

throws:

StepFailedException

Returns:

true if the element is present and visible; otherwise, false

Parameters:

to - represent a web element

timeOut - how many seconds to wait (maximum)

Did you get any problem using “WebUI.verifyElementVisible()” keyword or “WebUI.waitForElementVisible()” keyword? If so, it would be better asking about that incident, rather than talking about the docs.

Why not you share the log, screenshot, HTML sources etc as the following post explains:

My question is about the meaning of the word “visible” in Katalon documentation.

There is no accident (yet)) but you cannot use “WebUI.verifyElementVisible()” properly if you don’t know how exactly it’s supposed to work

That’s a fair question.

As far as I understand it, it is meant to mean actually visible, on screen, in the current viewport of the browser. Perhaps @Brandon_Hein knows more?

For the same reason you have doubts, I wrote my own WaitVisibleToHumans() - but even that has issues. When an element is semi-obscured by a dimmer, it’s considered not visible to humans. :confused:

But, back to the question - create a webpage with a super tall div. Place another element beneath it. Test to see if the bottom element is verifiably visible without scrolling. Post back your results (like a good engineer/scientist) :wink:

1 Like

According to the documentation, the keyword uses ExpectedConditions.visibilityOf() to determine visibility, and according to the documentation for ExpectedConditions.visibilityOf():

“Visibility means that the element is not only displayed but also has a height and width that is greater than 0.”

tl;dr I believe it checks the style attribute for display: none, and for height: 0 and width: 0. To Russ’s point, this means that even if you can’t see it with your eyeballs, it may still be considered visible by that definition.

2 Likes

… and hopefully includes,

visibility:visible
opacity:>0

and probably a few more quirks too quirky to mention. For completeness’ sake, here’s my JS…

/**
 * Returns 0 (zero) if element is visible, else a number representing why it is invisible.
 * @param {String} selector 
 */
function isVisibleToHumans(selector) {
  var elem = document.querySelectorAll(selector);
  var failMessage = "isVisibleToHumans " + selector + " fail at ";
  if(elem.length > 1) {
    console.log(failMessage + "1");
    return 1;
  }
  if(elem.length === 0) {
    console.log(failMessage + "2");
    return 2;
  }

  elem = elem[0];

  elem.scrollIntoView();

  var style = getComputedStyle(elem);
  if(style.visibility !== 'visible') {
    console.log(failMessage + "3");
    return 3;
  }
  
  if(style.display === 'none') {
    console.log(failMessage + "4");
    return 4;
  }

  if(style.opacity === 0) {
    console.log(failMessage + "5");
    return 5;
  }
  if(elem.offsetHeight + elem.offsetWidth 
      + elem.getBoundingClientRect().height
      + elem.getBoundingClientRect().width === 0) {
        console.log(failMessage + "6");
        return 6;
  }
  
  var center = {
      x: elem.getBoundingClientRect().left + elem.offsetWidth / 2,
      y: elem.getBoundingClientRect().top + elem.offsetHeight / 2
  };

  if(center.x < 0 || center.y < 0) {
    console.log(failMessage + "7");
    return 7;
  }

  //if(center.x > (document.documentElement.clientWidth || window.innerWidth)) return false;
  //if(center.y > (document.documentElement.clientHeight || window.innerHeight)) return false;
  var container = document.elementFromPoint(center.x, center.y);
  do {
      if(container === elem) return 0;
  } while (container = container.parentNode);
  console.log(failMessage + "8");
  return 8;
}

Note:
It’s a work-in-progress.
It’s derived from something I found on StackOverflow an age ago and lost the reference almost as long ago.

1 Like

Thank you, Russ_Thomas. I can try to do it when I a have a chance, though I’ve never created a webpage in my life. Still, like a good tester, I’d rather know the EXPECTED behavior. If the bottom element is not verifiably visible without scrolling, it might be that something is wrong with the page under test or with my test (nobody is perfect))

Right.

But note also that my approach has the intention of supporting a subsequent click action (or similar). The code actually performs a Web API scrollIntoView(). In other words, it will only fail when all reasonable attempts to reveal it have failed.

1 Like
<html>
  <title>My Web Page</title>
  <body>
    This is my web page
  </body>
</html>

Save that to a text file called my-first-web-page.html. Congratulations - you’re a web page author. :clap:

1 Like

Thank you Brandon_Hein. It’s really good to know that ““Visibility means that the element is not only displayed but also has a height and width that is greater than 0.””. Still, I’m not sure whether “visibility” means that an element “actually visible, on screen, in the current viewport of the browser”.

@gdearest07

You can use this as a starting point:

<html>
  <title>long page</title>
  <body>
    <div style="min-height:1500px;background-color:lightblue;">tall div</div>
    <div style="background-color:pink;color:red;">bottom element</div>
  </body>
</html>

If you use the following version in your browser address bar, it will display it directly (no need to save it as a file)…

data:text/html;charset=utf-8, <html><title>long page</title><body><div style="min-height:1500px;background-color:lightblue;">tall div</div><div style="background-color:pink;color:red;">bottom element</div></body>

But you can’t test the last one due to a bug in Katalon (Reminder @ThanhTo).

1 Like

Thank you, Russ_Thomas. I’m not sure what code and a Web API `scrollIntoView() you mean. I cannot see those in the your JS code posted above or https://github.com/katalon-studio/katalon-studio-testing-framework/blob/aec97e9b5ffb371676c205596ec2e54e7998528c/Include/scripts/groovy/com/kms/katalon/core/webui/keyword/builtin/WaitForElementVisibleKeyword.groovy posted above by Brandon.

1 Like

Thank you, Russ_Thomas ( I can see it now )) . Could you please let me know how I can use your function in Katalon ? That might sound like a dumb question but I’m not even a novice to Katalon yet. I’m just a guy who likes it and really want to use it for automation in our company.

Sorry. I realized midway through this discussion I’d led you down a path that required a lot of you - perhaps more than you are prepared for at this stage in your testing “journey”.

Javascript code (like my big block of code above) can be included in your test as a lengthy string of text and then executed by WebUI.executeJavaScript().

That’s a bit clunky, to say the least, but it works. Better still, I have it on good authority that the Katalon developers are bringing JavaScript to the forefront as a first-class citizen - so this clunkiness is likely to improve one day.

This (silly) example JavaScript will change the color of the page to pink:

String js = 'document.querySelector("body").style.backgroundColor = "pink";'
WebUI.executeJavaScript(js, null)

You can try the same code in the browser console

document.querySelector("body").style.backgroundColor = "pink"
1 Like

Thank you, Russ_Thomas. Sorry, I didn’t make myself clear. What I meant in my previous question was how your (or any) JS function can be used and RE-USED in Katalon? Suppose, your function works (a fair assumption, I guess). Obviously, that it can be included directly in the test script. But what if I need to use it in multiple tests. In my previous experience with Selenium projects I just put all JS scripts in the static functions in one of my util classes and just called those functions when I needed them. What approach should be used in Katalon? Thanks.

Sorry. You DID make yourself clear - my answer didn’t cover all the bases.

Utility functions (methods in Groovy-speak) are created by Custom Keywords. These are merely classes you create and add methods like you mentioned to them which you can call from any test case.

For all the background info, start here:

Once you’ve digested that, understand this: you don’t NEED to make keywords with @Keyword. You only need @Keyword if you want your methods to show up in Manual view. In script view, if you declared your methods as static, you can import them statically and re-use them anywhere:

import static myutils.* // or whatever you called them
1 Like