Checking if an item exists

I'm trying to check if an element exists but it doesn't work with a timeout error. From my observation, I learned that the driver first tries to figure out this element and then waits for the element to leave, instead of checking if the element exists or does not exist immediately. I have tried the methods below.

1. browser.element.all(selector)
2. browser.driver.findElements(selector)
3. browser.isElementPresent(browser.element(selector))
4. element(selector).isPresent()

      

Background: When the button is pressed, a modal will appear. It cancels and saves the buttons. When you click Cancel, the modal window disappears. Now I am trying to write a wait condition to check if the modal is gone or not.

All of the above doesn't work. Please tell me the correct way where I can check if an item exists immediately.

Below is the error for all of the above

Error: function timed out after 60000 milliseconds

      

I'm really not sure why Protractor can't help me just check if the element is not in the DOM. I've tried my best. Each method tries to find if an existing item transitions to a non-existent state or not. Then why are these many APIs if they do the same job.

+3


source to share


5 answers


Not sure why you are using browser.

for your selectors and not what it actually is selector

, but I suspect you have a lot of problems.

First, it .isPresent()

really asks if it is in dom; isDisplayed()

 asks, it can be seen. So your strategy will depend on whether your model is removed from the dom or hidden (eg, display:none

etc.).

Second, it looks like you disagree with the promise to return one of these methods. You also don't mention if you are using this in expect

(which automatically expects the promise to be fulfilled).

Third, it is not clear whether your modal selector returns one element or more (although you specify later using element.all

.

The long story is a little longer, here is an example of how you can check if your modal view is visible, given the assumption that your modal class .myModal

is the only one and it is removed from the dom when not displayed.



$('.myModal').isPresent().then(function(inDom) {
    return inDom; // returns bool
};

      

The above code grabs your element, checks if it is in the dom, processes the promise through, .then

and returns true / false if the element is in the dom.

However, your code may have multiple modals hidden via css. In this case, you need to find a strategy for this case. Maybe your code is adding a class .shown

to hidden elements? Great, check availability $('.myModal.shown')

. Maybe your code has multiple hidden modals in the dom ... less large, but you can loop through each element and check if any characters are displayed with isDisplayed()

.

Hope this helps a little ...

+3


source


I know this post is very old. But I found a way that might be helpful: I created a function that with 3 parameters

  • : the ElementFinder element that must not be present,
  • fieldName: the name of the log-only field,
  • present: boolean use this function to check if a field exists.

which can be used to validate every element present (and not) in the DOM



export async function checkField(field: any, fieldName: string, present?: any) {
  let text: string;
  if (present === false) {
    if (field.length > 0) {
      field.forEach(async el => {
        try {
          text = await el.getText();
          expect('should not be present (' + fieldName + ')').toEqual('but it is');
        } catch (e) {
          expect(el.isPresent()).toBe(present);
        }
      });
    } else {
      try {
        text = await field.getText();
        expect('should not be present (' + fieldName + ')').toEqual('but it is');
      } catch (e) {
        expect(field.isPresent()).toBe(present);
      }
    }
  } else {
    if (field.length > 0) {
      field.forEach(async el => {
        try {
          text = await el.getText();
          expect(el.isPresent()).toBe(true);
        } catch (e) {
          expect('element present (' + fieldName + ')').toEqual('but i can\'t find it');
          throw e;
        }
      });
    } else {
      try {
        text = await field.getText();
        expect(field.isPresent()).toBe(true);
      } catch (e) {
        expect('element present (' + fieldName + ')').toEqual('but i can\'t find it');
        throw e;
      }
    }
  }
}
      

Run codeHide result


this could obviously be better written, but it works right!

For anyone who might search this post again.

+1


source


Below is an example taken from the protractor api docs

expect(element(by.binding('notPresent')).isPresent()).toBe(false);

so your solution should be

expect(element(by.css('.elementClass')).isPresent()).toBe(false);

0


source


I had a similar problem, you might find it better to use expected conditions to wait for the modal to disappear before you try the wait operator.

var WaitForElement = function(item, timeout = 15000) {
  var el = element(by.css(item));
  var EC = protractor.ExpectedConditions;
  browser.wait(EC.not(EC.presenceOf(el)), timeout).then(function(){
    return;
  });
};

WaitForElement('.example').then(function() {
    expect(element(by.css('.example')).isPresent()).toBe(false);
}

      

This will cause the transporter to wait until the specified item disappears (".example" in this case) before running the wait statement, otherwise it will time out after 15 seconds and the wait will fail.

0


source


expect($(".example").isPresent()).toBe(false)

      

Each method in the transporter returns a promise. You have to use a helper to solve it. For example, the built-in wait function.

-1


source







All Articles