code: // Licensed to the Software Freedom Conservancy (SFC) under one
  // or more contributor license agreements.  See the NOTICE file
  // distributed with this work for additional information
  // regarding copyright ownership.  The SFC licenses this file
  // to you under the Apache License, Version 2.0 (the
  // "License"); you may not use this file except in compliance
  // with the License.  You may obtain a copy of the License at
  //
  //   http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing,
  // software distributed under the License is distributed on an
  // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  // KIND, either express or implied.  See the License for the
  // specific language governing permissions and limitations
  // under the License.
  
  package org.openqa.selenium;
  
  import java.util.Set;
  import org.openqa.selenium.support.ui.ExpectedCondition;
  
  public class WaitingConditions {
  
    private WaitingConditions() {
      // utility class
    }
  
    private abstract static class ElementTextComparator implements ExpectedCondition<String> {
      private String lastText = "";
      private final WebElement element;
      private final String expectedValue;
  
      ElementTextComparator(WebElement element, String expectedValue) {
        this.element = element;
        this.expectedValue = expectedValue;
      }
  
      @Override
      public String apply(WebDriver ignored) {
        lastText = element.getText();
        if (compareText(expectedValue, lastText)) {
          return lastText;
        }
  
        return null;
      }
  
      abstract boolean compareText(String expectedValue, String actualValue);
  
      @Override
      public String toString() {
        return "Element text mismatch: expected: " + expectedValue + " but was: '" + lastText + "'";
      }
    }
  
    public static ExpectedCondition<String> elementTextToEqual(
        final WebElement element, final String value) {
      return new ElementTextComparator(element, value) {
  
        @Override
        boolean compareText(String expectedValue, String actualValue) {
          return expectedValue.equals(actualValue);
        }
      };
    }
  
    public static ExpectedCondition<String> elementTextToContain(
        final WebElement element, final String value) {
      return new ElementTextComparator(element, value) {
  
        @Override
        boolean compareText(String expectedValue, String actualValue) {
          return actualValue.contains(expectedValue);
        }
      };
    }
  
    public static ExpectedCondition<String> elementTextToEqual(final By locator, final String value) {
      return new ExpectedCondition<String>() {
  
        @Override
        public String apply(WebDriver driver) {
          String text = driver.findElement(locator).getText();
          if (value.equals(text)) {
            return text;
          }
  
          return null;
        }
  
        @Override
        public String toString() {
          return "element text did not equal: " + value;
        }
      };
    }
  
    public static ExpectedCondition<String> elementValueToEqual(
        final WebElement element, final String expectedValue) {
      return new ExpectedCondition<String>() {
  
        private String lastValue = "";
  
        @Override
        public String apply(WebDriver ignored) {
          lastValue = element.getAttribute("value");
          if (expectedValue.equals(lastValue)) {
            return lastValue;
          }
          return null;
        }
  
        @Override
        public String toString() {
          return "element value to equal: " + expectedValue + " was: " + lastValue;
        }
      };
    }
  
    public static ExpectedCondition<String> pageSourceToContain(final String expectedText) {
      return new ExpectedCondition<String>() {
        @Override
        public String apply(WebDriver driver) {
          String source = driver.getPageSource();
  
          if (source.contains(expectedText)) {
            return source;
          }
          return null;
        }
  
        @Override
        public String toString() {
          return "Page source to contain: " + expectedText;
        }
      };
    }
  
    public static ExpectedCondition<Point> elementLocationToBe(
        final WebElement element, final Point expectedLocation) {
      return new ExpectedCondition<Point>() {
        private Point currentLocation = new Point(0, 0);
  
        @Override
        public Point apply(WebDriver ignored) {
          currentLocation = element.getLocation();
          if (currentLocation.equals(expectedLocation)) {
            return expectedLocation;
          }
  
          return null;
        }
  
        @Override
        public String toString() {
          return "location to be: " + expectedLocation + " is: " + currentLocation;
        }
      };
    }
  
    public static ExpectedCondition<Set<String>> windowHandleCountToBe(final int count) {
      return driver -> {
        Set<String> handles = driver.getWindowHandles();
        return handles.size() == count ? handles : null;
      };
    }
  
    public static ExpectedCondition<Set<String>> windowHandleCountToBeGreaterThan(final int count) {
      return driver -> {
        Set<String> handles = driver.getWindowHandles();
        return handles.size() > count ? handles : null;
      };
    }
  
    public static ExpectedCondition<String> newWindowIsOpened(final Set<String> originalHandles) {
      return driver ->
          driver.getWindowHandles().stream()
              .filter(handle -> !originalHandles.contains(handle))
              .findFirst()
              .orElse(null);
    }
  
    public static ExpectedCondition<WebDriver> windowToBeSwitchedToWithName(final String windowName) {
      return new ExpectedCondition<WebDriver>() {
  
        @Override
        public WebDriver apply(WebDriver driver) {
          return driver.switchTo().window(windowName);
        }
  
        @Override
        public String toString() {
          return String.format("window with name %s to exist", windowName);
        }
      };
    }
  }
  