NAV Navbar
java csharp python

JDI Light Framework

JDI Light is a powerful Test Automation Framework that helps to make your tests fast, sustainable and provides obvious and predictable test run results.

JDI Light is powered by Selenium and has simple integration with Selenium-based projects.

Allure Log

Highlights

Navigation

Introduction provides examples of common test automation tasks solved with JDI Light.

Tutorial walks you through adding JDI Light to your project, implementing test scenarios and using UI Elements. You also get to see how much JDI Light reduces the needed effort, compared to pure Selenium.

Theory addresses the key principles behind JDI Light framework and the tools it offers to put these principles into practice.

Documentation contains technical description of JDI Light features/settings and UI Element sets.

Introduction

Simple JDI examples

Create a simple Login test

First of all, let's see how JDI solves typical problems. Let's start with Login, since most tests start with signing in.

You can find a Java code example here.

Test Scenario

@Test
public void loginTest() {
    homePage.open();
    userIcon.click();
    loginForm.loginAs(DEFAULT_USER);
    homePage.checkOpened();
}
  1. Open Home Page (https://jdi-testing.github.io/jdi-light/index.html)
  2. Click on User Icon (to open login dialog)
  3. Log in as a default user:
    • Enter 'Roman' in login text field
    • Enter 'Jdi1234' in password text field
    • Press 'Enter'
  4. Verify that Home Page has been opened
[22:17.102  STEP] : Open 'Home Page'(url=>https://jdi-testing.github.io/jdi-light/index.html)
[22:23.617  STEP] : Click on 'User Icon'
[22:23.727  STEP] : Login as User (userName:epam; password:1234)
[22:24.516  STEP] : Check that 'Home Page' is opened (url CONTAINS '/index.html'; title EQUALS 'Home Page')

So simple! But there's more to it. Try to run this test in your IDE and see what you get...

Just move the allure-results folder to your local folder and run Maven > Plugins > Allure > allure:serve (see picture below).
Allure Serve

@JSite("https://jdi-testing.github.io/jdi-light/")
public class JdiTestSite {
    public static HomePage homePage;
}
@BeforeSuite(alwaysRun = true)
public static void setUp() {
    initElements(JdiTestSite.class);
}

@Url("/index.html") @Title("Home Page")
public class HomePage extends WebPage {
    @Css("form") public static LoginForm loginForm;
    @Css("img#user-icon") public static Icon userIcon;
}

public class LoginForm extends Form<User> {
    @Css("#name") TextField userName;
    @Css("#password")  TextField password;
    @Css("[type=submit]") Button enter;
}

UI Page Objects

Now let's have a look at Page Objects in JDI. For example, we used the following objects in the login test above:

Below you can find a common JDI project structure:

@Test
public void nonPageObjectTest() {
    WebPage.openUrl("https://jdi-testing.github.io/jdi-light/index.html");
    $("img#user-icon").click();
    $("form #name").input("Roman");
    $("form #password").input("Jdi1234");
    $("form [type=submit]").click();
    Assert.assertEquals(WebPage.getUrl(), "https://jdi-testing.github.io/jdi-light/index.html");
}
public class LoginForm extends Form<User> {
    TextField userName = $("#name");
    TextField password = $("#password");
    Button enter = $("[type=submit]");
}

Short term non-Page Object style

If you need a quick test (i.e. you don't need Page Objects), you can simply use jQuery/Selenide style without any additional code.

You can also directly initialize UI elements defined in your Page Objects if you don't like annotations.






Smart Test locators

See details and examples for Smart locators in the documentation

@Test
public void assertTest{
  title.is().text(containsString("jdi"));
  name.assertThat().text(is("Roman"));
  color.has().attr("color", is("red"))
}
@Test
public void chainAssertTest{
  title.assertThat()
    .text(containsString("jdi"))
    .attr("color", is("red"))
    .tag(is("h1"))
}
@Test
public void listAssertTest{
    searchResults.is().notEmpty();
    searchResults.assertThat()      
        .size(equalTo(10))
        .any(e -> e.name.equals("Jdi intro 2"))
        .each(e -> e.name.toLowerCase().contains("jdi"))
        .onlyOne(e -> e.name.contains("Jdi intro 1"))
        .noOne(e -> e.name.contains("Selenide"));
}
@Test
public void tableChainTest() {
    users.assertThat()
        .displayed().size(6).size(greaterThan(3))
        .notEmpty().row(d -> d.user.contains("Ivan"))
        .allRows(d -> d.user.length() > 4)
        .atLeast(3).rows(d -> d.type.contains("User"))       
        .row(SPIDER_MAN)
        .exact(2).rows(d -> d.description.contains(":VIP"))
        .exact(1).rows(SPIDER_MAN);
}

Asserts/Matchers integrated with elements

JDI has a really flexible set of matchers integrated into it.

Custom elements

public class Checklist extends HtmlElement {
    @Override
    public boolean isSelected() {
        return find("<<").hasClass("active");
    }
}
public class Checklist extends HtmlChecklist {
    @Override
    public boolean isSelected(HtmlElement value) {
        return hasClass("active") && attr("ui").equals("label");
    }
}
public class ContactForm extends Form<Contacts> {
    TextField name, lastName, position, passportNumber, passportSeria;
...
    @UI("['Submit']") public Button submit;

    @Override
    public void fillAction(Field field, Object element, Object parent, String setValue) {
        if (isInterface(field, TextField.class))
            ((TextField)element).higlight();
        super.fillAction(field, element, parent, setValue);
    }
}

JDI HTML elements can handle typical standard cases, but each application has its unique culture of layout development.

So if your developers are not following common standards, you can easily create a pack of elements specific to your application and use them with JDI. You can create your own elements or simply extend the existing ones, overriding a couple of methods.

Check these examples:

Menu Check item
Contact Form

Start a new project with JDI

You can start a new test automation project with JDI in mere seconds!
Just download one of the templates at Github JDI template repository.

Github link

Java + Allure + JUnit

Github link

CSharp + NUnit

Github link

How to improve your Selenium project with new capabilities in just a few minutes

Logging and Reporting

Tutorial

In this tutorial we’ll take a glance at JDI Light, a library that simplifies test automation, makes test run results stable, predictable and easy to maintain.

  1. Quick Start — a short instruction on how to add JDI Light to your project and perform its basic configuration.
  2. JDI Light at a glance — a few simple test examples with and without Page Objects. Typified UI Elements and logs in JDI Light.
  3. JDI Light Forms — a small complex element example that showcases the primary benefits of using JDI Light.
  4. UI Elements and optimization — a more sophisticated example elaborating on types of elements in JDI Light and demonstrating their capabilities.
  5. Reduce the amount of code with JDI Light — a concise example of how JDI Light can decrease the amount of code threefold compared to Selenium. Demonstrates that you can write clear and stable tests with 3 times less effort.

1. Quick Start

  1. Adding JDI Light to your projects
  2. A brief configuration overview

Let’s start from the beginning by adding JDI Light to our test project and going through the setup step by step.

Note: JDI Light ships with a template project that helps to save setup time.

Maven Dependencies

<dependency>
    <groupId>com.epam.jdi</groupId>
    <artifactId>jdi-light-html</artifactId>
    <version>RELEASE</version>
</dependency>

First, we need to add JDI Light to the dependency section of our pom.xml file:

The latest version can be found in the Maven Central Repository.

Configuration

That’s all! We don’t need to explicitly configure anything else to start working. By default, JDI Light will download Chrome driver automatically, set it up and run it as soon as we try to access the first page.

We can change the default settings by altering the test.properties file (located within src/test/resources directory).

src/test/resources/test.properties
driver=chrome
#driver.version=2.23 | LATEST
#timeout.wait.element=10
#timeout.wait.page=30
domain=https://jdi-testing.github.io/jdi-light/
#page.load.strategy=normal | eager | none
#browser.size=MAXIMIZE | 1024x762
...

Let’s have a detailed look at some options:

Note: you can find more examples in the documentation.

See the examples on Github

2. JDI Light at a glance

  1. Simple Open page test
  2. No Page Objects test example
  3. Page Objects test example

Let's start

@Test
public void openJDITestSite() {
    openUrl("https://jdi-testing.github.io/jdi-light/");
}

OK, now let’s write our first test case. We can open the JDI test site by using a static method openUrl() of the WebPage class.

WebPage provides essential methods to work with a browser: getUrl(), getTitle(), back(), forward(), getHtml(), refresh(). It also provides methods that allow to scroll up / down / left / right / to page top / to page bottom or zoom the page.

Simple test scenario

@Test
public void loginSimpleTest() {
    openUrl("https://jdi-testing.github.io/jdi-light/");
    $("img#user-icon").click();
    $("#name").sendKeys("Roman");
    $("#password").sendKeys("Jdi1234");
    $("#login-button").click();
    $("#user-name").is().displayed();
}

Now we can write a more involved typical test: log in to a page.

Every test should contain an assertion, so let’s add it to our test.

Code like this is easy to write. However, it will inevitably become hard to maintain as the number of tests grows and elements used get repeated throughout the tests.

For example, if we have an element found by $(".menu-about a") locator in more than 10 tests and its locator gets changed, we must go through all the tests and adjust the locator.

Page Objects are here to help us!

See the examples above on Github

Page Objects

public class HomePage extends WebPage {
    @FindBy(css = "img#user-icon") public WebElement userIcon;
    @FindBy(id = "name") public WebElement name;
    @FindBy(id = "password") public WebElement password;
    @FindBy(id = "login-button") public WebElement loginButton;
    @FindBy(id = "user-name") public WebElement userName;
}
public class HomePage extends WebPage {
    @UI("img#user-icon") public static Link userIcon;
    @UI("#name") public static TextField name;
    @UI("#password") public static TextField password;
    @UI("#login-button") public static Button loginButton;
    @UI("#user-name") public static Text userName;
}

Let’s develop our first simple Page Object and see how the test case will look like. We have our Home Page with several elements on it:

In order to make the code simple, in JDI Light we can use a unified annotation, @UI("..."). It handles both CSS and XPath locators, thus reducing the amount of code.

It's also a good use case for one of the main JDI Light features: typified elements like TextField, Button and Text.

The other great news is that we can make our Page Object elements static and keep tests clearer and more obvious.

@JSite("https://jdi-testing.github.io/jdi-light/")
public class SiteJdi {
    @Url("/") public static HomePage homePage;
    @Url("/contacts") @Title("Contact Form")
    public static ContactsPage contactPage;
}

Page Objects in JDI Light are called UI Objects and extend standard Selenium Page Objects' capabilities with typified elements like TextField, Button, Text etc. They also carry additional meta-information about a page, like URL and title. Pretty simple and obvious, isn’t it?

Page URLs are relative to the site domain specified in the @JSite annotation or in test.properties file.

Note: We won't be calling ContactsPage methods in this example; it is put here to demonstrate the usage of @Url and @Title annotations.

public interface TestsInit {
    @BeforeSuite(alwaysRun = true)
    static void setUp() {
        initElements(SiteJdi.class);
    }
}

And the last thing to consider before writing a test: all UI Objects of our application are initialized at once. We can do it with just a single line of code in the setup method that runs before all tests.

Note: in other frameworks we have to call initElements() for each Page Object.

public class PageObjectExample implements TestsInit {
    @Test
    public void loginTest() {
        homePage.open();
        userIcon.click();
        name.sendKeys("Roman");
        password.sendKeys("Jdi1234");
        loginButton.click();
        userName.assertThat().displayed();
    }
}

[ STEP 09:30.825] : Open 'Home Page'(url=https://jdi-testing.github.io/jdi-light/) (SiteJdi.homePage (url=https://jdi-testing.github.io/jdi-light/; title=))
[ STEP 09:37.188] : Click on 'User Icon' (HomePage.userIcon (css='img#user-icon'))
[ STEP 09:37.291] : Input 'Roman' in 'Name' (HomePage.name (css='#name'))
[ STEP 09:37.539] : Input 'Jdi1234' in 'Password' (HomePage.password (css='#password'))
[ STEP 09:37.756] : Click on 'Login Button' (HomePage.loginButton (css='#login-button'))
[ STEP 09:37.860] : Assert that 'User Name' is displayed (HomePage.userName (css='#user-name'))

[ STEP 11:16.923] : Open 'Home Page'(url=https://jdi-testing.github.io/jdi-light/)
[ STEP 11:22.983] : Click on 'User Icon'
[ STEP 11:23.088] : Input 'Roman' in 'Name'
[ STEP 11:23.369] : Input 'Jdi1234' in 'Password'
[ STEP 11:23.598] : Click on 'Login Button'
[ STEP 11:23.688] : Assert that 'User Name' is displayed

Now we can write our test using these UI Objects and execute it.

It lists exactly what we do in our test with all the details and without any extra effort on our part. Fabulous!

We can change the log level to STEP (just add logger.setLogLevel(STEP) to the setUp() method) and remove the details. The resulting log will be fit to share with a Customer, a Business Analyst or a Manual QA to let them know what our automated tests verify.

See PageObject examples in PageObjectExample.java on Github

3. JDI Light Forms

  1. Simple login test example. DataClass example
  2. Login Form in Data Driven Test approach
  3. Page Objects test example

Standard Login form

public class LoginForm extends Form<User> {
    @UI("#name") TextField name;
    @UI("#password") TextField password;
    @UI("#login-button") Button loginButton;
}
public class JDISite {
    @Url("/") public static HomePage homePage;
    public static LoginForm loginForm;
    ...
}
@Test
public void loginTest() {
    userIcon.click();
    loginForm.loginAs(ROMAN);
    userName.is().displayed();
}
public class User extends DataClass<User> {
    public String name, password;
}

Now we will optimize the previous example using forms.
Let's move the login form elements to a separate UI Object — LoginForm.
Then we'll set LoginForm as a root UI Object in our JDISite class.





Now we can rewrite our test in the following way:

I Like it!

ROMAN is a business entity of class User associated with Login Form. User class is a simple data class with two String fields that have the same names as TextField elements in LoginForm.

Aligning data class field names with form field names works for every kind of form field that supports fill-like interaction: TextField, TextArea, Checkbox, DropDown etc.

This gets covered more in depth in Contact Form example.

  User ROMAN = new User().set(c -> {
      c.name = "Roman"; c.password = "Jdi1234";
  } );
Output: ROMAN.toString() --> User(name:Roman; password:Jdi1234)
new User().equals(new User());

Any class can be used as data class, but extending it from DataClass (User extends DataClass<User> in this case) gives us additional benefits:

See this example in LoginExample.java on Github

Cover Login Form with Data-Driven tests

public class UsersDataProvider {
    public static User NO_PASSWORD = new User().set(c -> c.name = "Roman");
    public static User NO_CREDENTIALS = new User().set(c -> {
        c.name = ""; c.password = "";}
    );
    public static User WRONG_CREDENTIALS = new User().set(c -> {
        c.name = "Alex"; c.password = "Password";}
    );
    ...
}

public class LoginExample implements TestsInit {
    @BeforeMethod
    public void before() {
        loggedOut();
        loginFormShown();
    }
    @Test
    public void failedLoginTest1() {
        loginForm.loginAs(NO_PASSWORD);
        userName.is().hidden();
    }
    @Test
    public void failedLoginTest2() {
        loginForm.loginAs(WRONG_CREDENTIALS);
        userName.is().hidden();
    }
    @Test
    public void failedLoginTest3() {
        loginForm.loginAs(NO_CREDENTIALS);
        userName.is().hidden();
    }
    ...
}

This lets us easily increase the amount of different tests.

Let's cover login functionality with tests checking the following cases:

1) No password; 2. Wrong credentials; 3. No credentials.

In order to do this we will create a separate file (UsersDataProvider.java) for our test data and put User entities with the corresponding field values there.

Note: if you leave some fields null, this data will not be provided. Since we would like to validate empty values in fields for NO_CREDENTIALS user we'll have to set them as empty strings.

Now we can write our tests:

Note: we don't need to write any other code except test scenarios. Already written UI Objects will be enough.

Note: In order to be sure that the user is logged out and login form is opened before each test we can add these conditions as loggedOut() and loginFormShown()States in @BeforeMethod.

See this example in LoginExample.java on Github








Failed Login Form tests with Data Provider

public class UsersDataProvider {
    ...
    @DataProvider(name = "failedUsers")
    public static Object[][] failedUsers() {
        return new User[][]{{NO_PASSWORD}, {NO_CREDENTIALS}, {WRONG_CREDENTIALS}};
    }

But the scenarios in previous example are pretty much the same. The only difference is the test data. We can simplify our tests using DataProvider.
Let's add failedUsers() method that returns test data for our cases as a 2D array of User instances to our UsersDataProvider.java file, then mark this method with @DataProvider(name = "failedUsers").

public class UsersDataProvider {
    ...
    @Test(dataProvider = "failedUsers", dataProviderClass = UsersDataProvider.class)
    public void dataFailedLoginTest(User user) {
        loginForm.loginAs(user);
        userName.is().hidden();
    }

As a next step, we will create one common test scenario that accepts User instance as a parameter.

And the last step is just to link our test to the data provider method using @Test annotation attributes.

That's it! If we run this scenario, it will execute 3 tests that validate different cases of login failure. This way you can easily manage same scenarios with different test data, increase testing coverage, add new data sets or update them without changing the actual tests. It's that simple!

I Like it!
See this example in LoginExample.java on Github

4. UI Elements and optimization

  1. Main UI Element types in JDI Light and a few examples.
  2. Complex Contact Form example.
  3. Check and verify Form methods. Errors in logs.
  4. 5 Ways to describe Form with a complex Selenium example (17 lines) to 1 line Form

UI Elements on Contact Form

We've had a quick look at JDI Light; now let's look closer at UI Elements. In JDI we have 3 kinds of elements:

  1. Common Elements: Button, TextField, Text, Checkbox etc. Some of them we have already used in Login Form. All of these elements have simple structure and can be described using one locator or Selenium element.

    Note: See the full list and more details in Documentation

  2. Complex elements like Dropdown, Checklist, RadioButtons, MultiSelect, DataList etc. They represent actual UI elements that encompass the functionality of multiple Common Elements. For example, Dropdown may be regarded as combination of elements that represent value, caret (expand dropdown) arrow and list of options; Checklist is basically a list of Checkbox elements.

    Note: See the full list and more details in Documentation

  3. Composite elements are typified Page Objects. These are WebPage, Form, Section: classes having Common, Complex Elements or sub-sections as their fields.

    Note: See the full list and more details in Documentation

Let's look at an example: Contact Form on Contacts page.

This form, compared to the Login Form, has more different UI elements. Let's describe it.

public class ContactForm extends Form<ContactInfo> {
    @UI("#passport") Checkbox passport;
    @UI("#name") TextField name;
    @UI("#last-name") TextField lastName;
    @UI("#position") TextField position;
    @UI("#passport-number") TextField passportNumber;
    @UI("#passport-seria") TextField passportSeria;
    @UI("#accept-conditions") public Checkbox acceptConditions;
    @UI("#description") TextArea description;
    @UI("button[type=submit]") Button submit;
    ...
}

Here we have Common elements:

5 TextField elements (name, lastName, position, passportNumber, passportSeria)
TextField
2 Checkbox elements (passport, acceptConditions)
Checkbox
1 TextArea (description)
TextArea
1 Button (submit)
Button

public class ContactForm extends Form<ContactInfo> {
    ...
    @UI("#gender") Dropdown gender;
    @UI("#religion") Combobox religion;
    @UI("#weather") MultiDropdown weather;
}
// Selenium implementation that takes 21 lines of code instead of 1 line in JDI Light, namely:
// @UI("#weather") MultiDropdown weather
@FindBy(css ="#weather .caret") WebElement weatherExpand;
@FindBy(css ="#weather label") List<WebElement> weatherList;
@FindBy(css ="#weather button") WebElement weatherValue;
@FindBy(css ="#weather ul") WebElement weatherIsExpanded;
private boolean weatherIsExpanded() {
    return weatherIsExpanded.getAttribute("style").equals("display: block;");
}
public void select(String value) {
    if (!weatherIsExpanded())
        weatherExpand.click();
    String[] values = value.split(", ");
    for (String val : values) {
        for (WebElement listOption : weatherList) {
            if (listOption.getText().trim().equals(val))
                listOption.click();
        }
    }
}
public String getValue() {
    return weatherValue.getText();
}

And Complex elements:

Dropdown (gender) — An element with one selectable value, expand arrow and a list of options.
Dropdown
Combobox (religion) — Mix of Dropdown and TextField. You can select a value from a list of options or enter your own value.
Combobox
MultiDropdown (weather) — Dropdown that allows selection of multiple options. We also provide an example of Selenium implementation of equivalent functionality for comparison.
MultiDropdown

@Url("/contacts") @Title("Contact Form")
public class ContactPage extends WebPage {
    @UI("#contact-form") public static ContactForm contactForm;
}

And the Contact Form itself is a Composite UI Object (PageObject with additional capabilities in JDI).

We will call the Contact Form placed on another Composite Page Object a Contact Page.

Pay attention to the fact that Contact Form and Contact Page have the additional meta-information:

public class ContactInfo extends DataClass<ContactInfo> {
    public String passport, name, lastName, position, passportNumber, 
        passportSeria, gender, religion, weather, acceptConditions, description;
}

The next important points of attention are ContactPage extends WebPage and ContactForm extends Form<ContactInfo> inheritance declarations. They grant these Page Objects webpage and form functionality and allow access to their meta-information.
ContactInfo, the data class to be used with ContactForm, looks pretty much the same as the data class for Login Form. Each field that is used when filling the form is a String.

@UI("img#user-icon") public static Link userIcon;
@UI("#user-name") public static Text userName;
@UI(".sidebar-menu span") public static Menu sideMenu;

We also have a few Common elements that are placed directly in Site:

  1. Link element userIcon and Text element userName; we have already been using them in earlier tests.
  2. One new Complex element, Menu, representing the list of links in the left sidebar. This element is also found by one locator but contains 16 menu items, and you can also select the item you need by its name defined in MenuOptions enum (found in src/main/java/jdisite/enums).

Contact Form test scenario

@Test
public void simpleContactFormTest() {
    sideMenu.select("Contact form");
    contactPage.checkOpened();
    contactForm.submit(FULL_CONTACT);
    contactForm.check(FULL_CONTACT);
}

Now let's write a complex test that:

This is just as simple as filling the Login Form!
Amazing!

public static ContactInfo FULL_CONTACT = new ContactInfo().set(c -> {
    c.name = "Roman"; c.lastName = "Full Contact"; c.position = "ChiefQA"; 
    c.passportNumber = 4321; c.passportSeria = 123456; 
    c.description = "JDI - awesome UI automation tool";

    c.gender = "Female"; c.religion = "Other"; c.weather = "Sun, Snow";
    c.acceptConditions = true; c.passport = true;
    }
);

The most complicated part is creating the test data that we would like to utilize:

public static ContactInfo SIMPLE_CONTACT = new ContactInfo().set(c -> {
    c.name = "Roman"; c.lastName = "Iovlev"; c.position = "ChiefQA";
    c.passportNumber = 4321; c.passportSeria = 123456; }
);
@Test
public void simpleContactFormTest() {
    sideMenu.select(ContactForm);
    contactPage.checkOpened();
    contactForm.submit(SIMPLE_CONTACT);
    contactForm.check(SIMPLE_CONTACT);
}

Now if we would like to fill only the TextField elements, we only need to change our test data.

Note: In the second example we use MenuOptions enum value (ContactForm) to select a sideMenu item. It reduces the chance of making a mistake by limiting the choice of options. The enum is found at src/main/java/jdisite/enums.

See this example in ContactFormExamples.java on Github








Failed form example in logs

@Test
public void failCheckExample() {
    sideMenu.select(ContactForm);
    contactPage.checkOpened();
    contactForm.fill(FULL_CONTACT);
    contactForm.acceptConditions.uncheck();
    contactForm.submit();
    List<String> result = contactForm.verify(FULL_CONTACT);
    assertThat(result, Matchers.hasSize(1));
    assertThat(result, hasItem("Field 'acceptConditions' (Actual: 'false' <> Expected: 'true')"));
}

Now let's fail the validation of our form and see how JDI Light will display the failure results. We can build upon the previous example and just change some field before the check. Let's write a test that does this, execute it and observe the results.

Forms in JDI have two methods which verify the entered data:

In our example we revert one field, acceptConditions, to an unchecked state, and the resulting exception gets presented in a clear way (pictured to the right):

"Field 'acceptConditions' (Actual: 'false' <> Expected: 'true')"

You can find this example in ContactFormExamples.java on Github

Using Forms in different ways

    @BeforeMethod
    public void before() {
        loggedOut();
        if (loginForm.isHidden())
            userIcon.click();
    }

We've had a first look at UI Elements in JDI Light and at the capabilities of Forms, and now we can look deeper at Form initialization and see how it can help you write less code.

Let's start with a simple Form — Login.

We're planning to have a lot of tests with the preconditions "User is logged out" and "Login form is opened", so let's write a corresponding @BeforeMethod state for this set of test cases.

//Example 1
public class SeleniumLoginForm {
    @FindBy(id = "name") public WebElement name;
    @FindBy(id = "password") public WebElement password;
    @FindBy(id = "login-button") public WebElement loginButton;

    public void loginAs(User user) {
        name.sendKeys(user.name);
        password.sendKeys(user.password);
        loginButton.click();
    }
}
//Example 2
public class SeleniumLoginForm {
    ...
    // 3 lines for Elements
    public void loginAs(User user) {
        if (user.name != null) {
            name.clear();
            name.sendKeys(user.name);
        }
        if (user.password != null) {
            password.clear();
            password.sendKeys(user.password);
        }
        loginButton.click();
    }
}
//now we should add the class SeleniumLoginForm on JDISite.java:
public static SeleniumLoginForm seleniumLoginForm;

public class SelenideLoginForm {
    UIElement name = $("#name"), 
          password = $("#password"), 
       loginButton = $("#login-button");
    // + Same 11 rows for methods like in Selenium
    ...
}
//now we should add the class SelenideLoginForm on JDISite.java:
public static SelenideLoginForm selenideLoginForm;

public class LoginForm extends Form<User> {
    @UI("#name") TextField name;
    @UI("#password") TextField password;
    @UI("#login-button") Button loginButton;
}
//now we should add the class LoginForm on JDISite.java:
public static LoginForm loginForm;

public class LoginFormSmart extends Form<User> {
    TextField name, password;
    Button loginButton;
}
//now we should add the class LoginFormSmart on JDISite.java:
public static LoginFormSmart loginFormSmart;

In JDI Light we can describe a Form in different styles:

Selenium — a typical Page Object with WebElements and @FindBy annotations, Selenium actions upon Web Elements and no inheritance from JDI Light classes. Code like that will still work in pure Selenium projects without JDI.

See Example 1

But for cases where we would like to fill a form with different values, but it's not guaranteed that all form fields are empty, we need to extend our loginAs method and make it more complex and stable.

See Example 2

See the example in Selenium LoginForm.java on Github












JQuery/Selenide — Selenide or jQuery-like style, where instead of @FindBy annotations you can use direct initialization.
See the example in SelenideLoginForm.java on Github



Regular JDI Light Form — typical JDI Forms with typified elements, @UI annotations, extending from Form without overriding fill/check methods.
See the example in LoginForm.java on Github


JDI Light Form with smart locators — If it's possible to align field names with locators, you can use smart locators for elements and remove locator annotations from Forms. This also allows you to declare form fields with the same type in one line, separated by commas.

See more details and examples for Smart locators in documentation
See example in LoginFormSmart.java on Github

on JDISite.java >> public static Form<User> lightLoginForm;

If your Form has only TextField elements and buttons, instead of describing a UI object you can simply write a single line in the corresponding page class or in the root Site class:

This allows us to construct Login Forms in 1 line instead of 17!

Nice job man!

5. Reduce the amount of code with JDI Light

  1. Initialize Driver in Selenium and JDI Light
  2. Page Objects code
  3. Compare Login Form code
  4. Reduce Complex Contact Form Page Object code from 97 lines (Selenium) to 8 lines of code (JDI Light)
  5. Test Data in Selenium and JDI Light
  6. Discuss example results

Now we know enough about Forms, so let's see how this can help us write code faster (by writing less code).

Let's try to code in Selenium the same Fill Contact Form test scenario that we have already covered with JDI Light:

Note: You can find all the Selenium code here.
The same scenario with JDI Light is found here.

In this example I will develop Selenium code solution as effectively as possible while trying to keep the same look and feel of the test scenario.

At the same time, we will see how this code can be optimized using knowledge we got from Use Forms in different ways topic.

I will list the amount of lines of code we wrote for each action in brackets.

1. Set up and run Chrome driver

public static WebDriver DRIVER;
public static void runChromeDriver() {
    System.setProperty("webdriver.chrome.driver", "C:\\Selenium\\chromedriver.exe");
    DRIVER = new ChromeDriver();
    DRIVER.manage().window().maximize();
}

Selenium: (6 lines of code)
Here it is done with a simple method, runChromeDriver().

Note: To run the driver in Selenium you need to download the latest version from the official site and put it in Selenium folder.

JDI Light: (0 lines of code)
You don't need to write any code for this. By default, the latest version of ChromeDriver will be downloaded automatically.

2. Create Page Objects for Home and Contact pages

public class HomePage {
    public static final String URL = "https://jdi-testing.github.io/jdi-light/";
    @FindBy(id ="user-icon") public static WebElement userIcon;
    @FindBy(id ="user-name") public static WebElement userName;
}
public static HomePage homePage = initElements(DRIVER, HomePage.class);

public class ContactPage {
    public static final String URL = "https://jdi-testing.github.io/jdi-light/contacts.html";
    public static final String TITLE = "Contact Form";    
    public static ContactForm contactForm = initElements(DRIVER, ContactForm.class);
}
public static ContactPage contactPage = initElements(DRIVER, ContactPage.class);

Selenium: (12 lines of code)
Using PageFactory.initElements(), we can create simple Page Objects with minimum code like in the example.

If you want to have cool pages in Selenium, you can use BasePage, which handles all the standard stuff related to opening and checking pages.

Note: I hope this "BasePage" approach will be useful for your Selenium projects.







@Url("/")
public class HomePage extends WebPage {
    @UI("#user-icon") public static Link userIcon;
    @UI("#user-name") public static Text userName;
}
public static HomePage homePage;

@Url("/contacts") @Title("Contact Form")
public class ContactPage extends WebPage {
    @UI("#contact-form") public static ContactForm contactForm;
}
public static ContactPage contactPage;

JDI Light: (11 lines of code)
In JDI Light we already have all the functions related to webpages. You can find them in the WebPage class, so you just need to extend your Page Object from it and use @Url and @Title annotations to set page metadata.

The code for UI Objects in Selenium and JDI Light in this case looks pretty much the same.
However, there are several points worth noting:

public class LoginForm {
    @FindBy(id = "name") WebElement name;
    @FindBy(id = "password") WebElement password;
    @FindBy(id = "login-button") WebElement loginButton;

    public void loginAs(User user) {
        if (user.name != null) {
            name.clear();
            name.sendKeys(user.name);
        }
        if (user.password != null) {
            password.clear();
            password.sendKeys(user.password);
        }
        loginButton.click();
    }
    public boolean isHidden() {
        return !name.isDisplayed();
    }
}
public static LoginForm loginForm = initElements(DRIVER, LoginForm.class);

3. Create a simple Login Form

Selenium: (21 lines of code)
This form contains WebElements (name, password, loginButton) and actions like loginAs() and isHidden().

Code example











JDI Light(1 line of code)

public static Form<User> loginForm;

In JDI Light you don't need to create a UI Object for such a simple form. Just declare it in your site class.

Note: And, of course, you don't need to initialize this form.

4. Creating a complex Contact Form

In total, we have 97 lines of code for Selenium and only 8 lines of code in JDI Light, but let's go step by step and see the difference in details.

Selenium Contact Form code (97)
JDI Light Contact Form code (8)

Note: Unfortunately, we can't use one-liner Form in this case because the form has elements of different kinds, but we still can use short form descriptions with Smart locators. Just describe element types and names and use one-line initialization with your root "#contact-form" locator.

    @FindBy(css ="#contact-form #name") WebElement name; 
    // +4 more TextFields
    @FindBy(css ="#contact-form #accept-conditions") WebElement acceptConditionsCheckbox;
    @FindBy(css ="#contact-form #passport") WebElement passportCheckbox;
    @FindBy(css ="#contact-form #description") WebElement descriptionText;
    @FindBy(css ="#contact-form [type=submit]") WebElement submitButton;

Selenium: (9 lines of code)
In Selenium we have to describe all elements of the form. This is easy to do for simple elements like TextField, Checkbox, TextArea and buttons.

Note: You must add #contact-form to some element locators.

And because WebElement doesn't give us any clues about the type of element, it is a good practice to denote an element type in a variable name.

    TextField name, lastName, position, passportNumber, passportSeria;
    Checkbox passport, acceptConditions;
    TextArea description;

JDI Light: (3 lines of code)
In JDI Light we just need to describe the types of elements and list them for each type. In this example, locators align with field names, so we can utilize Smart locators without writing explicit ones.

    // Dropdown
    @FindBy(id = "gender") WebElement gender;
    private Select gender() { 
        return new Select(gender); 
    }
    // Combobox
    @FindBy(id = "religion") WebElement religion;
    // MultiDropdown
    @FindBy(css ="#weather .caret") WebElement weatherExpand;
    @FindBy(css ="#weather label") List<WebElement> weatherList;
    @FindBy(css ="#weather button") WebElement weatherValue;
    @FindBy(css ="#weather ul") WebElement weatherIsExpanded;
    private boolean weatherIsExpanded() {
        return weatherIsExpanded.getAttribute("style").equals("display: block;");
    }
    private void selectWeather(String value) {
        if (!weatherIsExpanded())
            weatherExpand.click();
        String[] values = value.split(", ");
        for (String val : values) {
            for (WebElement listOption : weatherList) {
                if (listOption.getText().trim().equals(val))
                    listOption.click();
            }
        }
    }

Selenium: (23 lines of code)
The situation with Complex elements is more interesting:

Instead of Dropdown we can use Select class from selenium-support package and WebElement + gender() method. These are enough to handle all actions.

Instead of Combobox we can use a one-line WebElement (just using it as a standard TextField).

But instead of MultiDropdown we'll need to add 4 WebElements and a few methods: select and isExpanded. The general problem with Complex elements in standard Selenium approach is that we have to create methods like these for every equivalent of Dropdown, MultiDropdown etc. JDI Light allows to define an element once (or pick one from element library) and then just use it in one line in all Page Objects.

MultiDropdown example

    Dropdown gender;
    Combobox religion;
    MultiDropdown weather;

JDI Light: (3 lines of code)
In JDI Light it is as simple as for Common elements.

Note: They are so short that we could write them in one line, but let's keep each on its own line.

public void submit(ContactInfo contact) {
    if (contact.name != null) {
        nameTextField.clear();
        nameTextField.sendKeys(contact.name);
    }
    // +6 more elements, 4 lines each including Combobox and TextArea
    // Dropdown
    if (contact.gender != null) {
        gender().selectByVisibleText(contact.gender);
    }
    // MultiDropdown
    if (contact.weather != null) {
        selectWeather(contact.weather);
    }
    // Checkboxes
    if (contact.passport && !passportCheckbox.isSelected() ||
            !contact.passport && passportCheckbox.isSelected())
        passportCheckbox.click();
    if (contact.acceptConditions && !acceptConditionsCheckbox.isSelected() ||
            !contact.acceptConditions && acceptConditionsCheckbox.isSelected())
        acceptConditionsCheckbox.click();
    submitButton.click();
}
public void check(ContactInfo contact) {
    //  20 lines to validate contact
}

Selenium: (65(37) lines of code)
We'll need to write two methods: submit and check.

Like with the Login Form, in order to manage different test data fed into the Contact Form we'll have to check values for null. We can avoid this check in only one case (for example, just fill all fields with null and save a few lines of code).
Using a flexible approach, we need 43 + 22 = 65 lines of code.

We can improve this code by using a common method that clears and sends keys to an abstract WebElement: this will reduce our code to 55 lines.

If we remove null validations, it will make our methods less universal, but will save additional 18 lines and reduce the code to 37 lines for Form methods.

Selenium Contact Form code (97)
Short Selenium Contact Form code (69)






JDI Light: (0 lines of code)
In JDI Light we don't need methods for these typical actions. Standard Form actions are flexible and allow to operate with any kind of data.
JDI Light Contact Form code (8)

5. Test Data

public class User {
    public String name, password;
    // + 3 lines constructor
    // + 8 lines set methods
    // + 16 lines to Override equals, hashCode and toString
}
public class ContactInfo {
    public String name, lastName, position, gender, religion, weather, description;
    public int passportNumber, passportSeria;
    public boolean passport, acceptConditions;
    // + 16 lines constructor
    // + 44 lines set methods
    // + 30 lines to Override equals, hashCode and toString
}
public static User ROMAN = new User("Roman", "Jdi1234");
public static ContactInfo SIMPLE_CONTACT = new ContactInfo()
    .setName("Roman").setLastName("Iovlev").setPosition("ChiefQA")
    .setPassportNumber(4321).setPassportSeria(123456)
    .setDescription("JDI - awesome UI autoamtion tool");
public static ContactInfo FULL_CONTACT = new ContactInfo(
    "Roman", "Full Contact", "ChiefQA", "Female", "Other", 
    "Sun, Snow", "JDI - awesome UI automation tool",
    4321, 123456, true, false
);

Selenium: (134 lines of code)
For a simple User entity with two fields we should have at least one constructor, but it would be nice to override equals(), hashCode() and toString() methods in order to have a log-friendly representation of an entity and ability to compare the actual and expected results by class fields. Additionally, if we want to have the ability to set up different data, we have to create setter methods for each field.

You can generate all of these methods using "Generate" option in IntelliJ IDEA (right-click the data class and select "Generate").

We need at least 7 lines of code, but for a reusable entity we should write 31 lines of code.
The same holds true for ContactInfo and for any Data entity in the standard approach. For ContactInfo the full declaration is more important because we plan to make use of more fields, and it will take more lines of code.

After these manipulations, we can create transparent test data.

User data
ContactInfo data
User Roman
Full and Simple Contact info

public class User extends DataClass<User> {
    public String name, password;
}
public class ContactInfo extends DataClass<ContactInfo> {
    public String name, lastName, position, gender, religion, weather, description;
    public int passportNumber, passportSeria = -1;
    public boolean passport, acceptConditions;
}
public static User ROMAN = new User().set(c -> {
    c.name = "Roman"; c.password = "Jdi1234";}
);
public static ContactInfo SIMPLE_CONTACT = new ContactInfo().set(c -> {
    c.name = "Roman"; c.lastName = "Iovlev"; c.position = "ChiefQA";
    c.passportNumber = 4321; c.passportSeria = 123456;
    c.description = "JDI - awesome UI autoamtion tool"; }
);
public static ContactInfo FULL_CONTACT = new ContactInfo().set(c -> {
    c.name = "Roman"; c.lastName = "Full Contact"; c.position = "ChiefQA";
    c.religion = "Other"; c.weather = "Sun, Snow"; c.acceptConditions = true;
    c.gender = "Female"; c.passportNumber = 4321; c.passportSeria = 123456;
    c.passport = true; c.description = "JDI - awesome UI automation tool"; }
);

JDI Light: (22 lines of code)
To create Test Data in JDI Light, we can use DataClass. It allows us to create different test data, compare data entities, print their meaningful representations and at the same preserve code clearness.

No constructors, no method overriding and with all functions in place thanks to DataClass.

User data
ContactInfo data
Test Data









6. Conclusion

// Selenium Init
@BeforeSuite(alwaysRun = true)
static void setUp() {
    runChromeDriver();
    DRIVER.navigate().to(HomePage.URL);
}
// JDI Light Init
@BeforeSuite(alwaysRun = true)
static void setUp() {
    initElements(JDISite.class);
    homePage.open();
}
// Selenium Test Scenarios
@BeforeMethod
public void before() {
    loggedIn();
    selectInMenu("Contact form");
}
@Test
public void submitContactDataTest() {
    assertEquals(DRIVER.getCurrentUrl(), ContactPage.URL);
    assertEquals(DRIVER.getTitle(), ContactPage.TITLE);
    contactForm.submit(FULL_CONTACT);
    contactForm.check(FULL_CONTACT);
}
@Test
public void submitContactSimpleDataTest() {
    assertEquals(DRIVER.getCurrentUrl(), ContactPage.URL);
    assertEquals(DRIVER.getTitle(), ContactPage.TITLE);
    contactForm.submit(SIMPLE_CONTACT);
    contactForm.check(SIMPLE_CONTACT);
}
// JDI Test Scenarios
@BeforeMethod
public void before() {
    loggedIn();
    sideMenu.select("Contact form");
}
@Test
public void submitContactFormTest() {
    contactPage.checkOpened();
    contactForm.submit(FULL_CONTACT);
    contactForm.check(FULL_CONTACT);
}
@Test
public void simpleContactFormTest() {
    contactPage.checkOpened();
    contactForm.submit(SIMPLE_CONTACT);
    contactForm.check(SIMPLE_CONTACT);
}

As a result, we have test scenarios that look pretty much the same in Selenium and JDI Light, but the amount of code and time spent writing the code is significantly different.

You can find the complete project code in the "result" branch of Selenium and JDI Light example repositories.

Statistical results:
Selenium Statistic
JDI Light Statistic

In our example, we wrote 3 times less amount of code with JDI Light.

This means that if a regular Test Automation engineer writes these tests using Selenium, it will take about 1 working day, while using JDI Light this work will only take 2-3 hours. In other words, an engineer can automate 3 times more test cases in the same period of time.

Note: You can try to automate this test scenario by yourself from scratch without clues and check how much time this will take in your case.

But JDI Light does not only save your time. Less amount of code increases code clearness.

In addition, if you run test scenarios with JDI Light, you will get logs of all your actions in a readable format. If you would like to have the same format of logs in Selenium, you need to write additional 30-50 lines of code for this example and spend 5-10% of your total effort on logs.

Note: JDI Light removes only waste code and keeps all the business-relevant parts in place.

Lesser amount of code, stable tests and clear logs will reduce maintenance effort during regression testing and increase the credibility of your tests, because with JDI Light, once tests are written, they will only fail in case of real application changes or performance issues, but not because of test instability.

JDI Light in BDD Style (even for Manual QA)

TBD

Create Custom controls

TBD

JDI settings at a glance

TBD

Test Framework structure

TBD

Theory

UI Elements

In order to effectively utilize Page Objects pattern we need to place elements on pages. Instead of Selenium WebElement objects that basically represent HTML tags, in JDI we introduce UI Elements that represent UI elements interacted with by an actual user.

JDI provides the ability to create your own elements or use standard elements from a rich collection.

Common elements

@UI("input[type=text].name") public TextField name;
@UI("h1") public Label label;
@UI("//div[@name='disclamer']") public Text disclaimer;
@UI("textarea[ui=description]") public TextArea description;
@UI("//*[text()='Submit']") public Button submit;

In JDI we have the following Common elements:

Label, Button, Checkbox, ColorPicker, DateTimeSelector, FileInput, Icon, Image, Link, Menu, NumberSelector, ProgressBar, Range, Text, TextField, TextArea, Title.

Complex elements

@UI(".colors") public Dropdown colors;
@UI("input[type=checkbox].conditions") public Checklist acceptConditions;
@JDropdown(root = ".colors", value = ".dropdown-value", list = "li", expand = ".caret")
public Dropdown colors;
@UI("[ui=label] li") public JList<Labels> tabs;
@UI("//button[text()='%s']") public JList<Button> buttons;

In addition to Common elements, JDI Light features Complex elements: they represent UI elements encompassing the functionality of multiple Common elements.

Some Complex elements may be regarded as sets of similar Common elements (something you would likely implement as List<WebElement> in Selenium). Typical examples of such Complex elements are Menu, Checklist, RadioButtons, or Tabs.

Note: You can still use lists of Common elements like List<Button> or List<Label> if need be.

Other Complex elements may be regarded as made up of different Common elements. Typical examples would be Dropdown or Combobox.

In JDI we have the following Complex elements:

RadioButtons, Table, DataTable, Dropdown, MultiDropdown, DataList, Checklist, MultiSelector, Combobox.

Composite elements

public class LoginForm extends Form<User> {
    public TextField name, password;
    @UI("//*[text()='Submit']") public Button submit;
    ...
}
public class TopPanel extends Section {
    @UI("form.login") public LoginForm loginForm;
    @UI("h1") public Label label;
    @UI(".colors") public Dropdown colors;
    ...
}
@Url("/login.html") @Title("Login to JDI")
public class LoginPage extends WebPage {
    @UI(".top-panel") public TopPanel topPanel;
    ...
}

Composite elements represent webpages or webpage sections and are mainly used as containers for elements and actions. Typical examples of Composite elements are WebPage and Section.

Composite elements can also have a locator that defines a context for all elements within them. This means that all elements in a composite element will be searched relatively under this locator.

Composite elements might have predefined actions like fill, submit and check for Form, or open(), checkOpened() for WebPage.

Remember that you can create your own Composite elements with JDI Light when you need to describe sections like Header, Navigation Bar, Footer, Sidebar, Advertisement Section or the main section of a page.

In JDI we have the following Composite elements:

Section, Form, WebPage.

UI Objects

public class AwesomeApplication {
    public LoginPage loginPage;
    @UI(".nav li") public Menu navigation;
}
@Url("/login.html") @Title("Login to JDI")
public class LoginPage extends WebPage {
    @UI(".top-panel") public TopPanel topPanel;
    ...
}
public class TopPanel extends Section {
    @UI("form.login") public LoginForm loginForm;
    @UI("h1") public Label label;
    @UI(".colors") public Dropdown colors;
    ...
}

UI Objects extend the standard Page Objects pattern with UI Elements and allow users to split pages into sections.

A typical UI object structure consists of:

Entity Driven Testing

(1)
public class LoginForm extends Form<User> {
    public TextField name, password;
    @UI("//*[text()='Submit']") public Button submit;
    ...
}
public class User extends DataClass<User> {
    public String name, password;
}
@Test(dataProvider = "users")
public void loginTest(User user) {
    loginForm.loginAs(user);
}
(2)
@UI("#user-table")
public static DataTable<?, UserInfo> userTable;
public class UserInfo extends DataClass<UserInfo> {
    public String number, type, user, description;
}
@Test
public void userInfoTest() {
    usersListPage.open();
    userTable.has().value(SPIDER_MAN, inRow(2));
    userTable.assertThat()
      .all().rows(d -> d.user.length() > 4)
      .no().rows(d -> isBlank(d.user))
      .atLeast(3).rows(d -> d.type.contains("User"))
      .exact(1).rows(SPIDER_MAN);
    assertEquals(userTable.dataRow("Wolverine").type, "Admin");
}
(3)
@UI(".search-results li") public DataList<?, Result> resultsList;
public class Result extends DataClass<Result> {
    public String name, description, link;
}
@Test
public void resultsTest() {
  resultsList.assertThat()
    .value(containsString("name:JDI FACEBOOK GROUP; description:English Community Facebook group"))
    .any(e -> e.description.toLowerCase().contains("jdi"))
    .each(e -> e.name.toLowerCase().contains("jdi"))
    .onlyOne(e -> e.name.contains("OWNER"))
    .noOne(e -> e.name.equalsIgnoreCase("Selenide"));

  resultsList.assertThat(not(empty()))
    .and(hasSize(greaterThan(2)))
    .and(hasItem(CORRECT))
    .and(hasItems(CORRECT, CORRECT_2, CORRECT_3))
    .and(not(hasItem(CORRUPTED)))
    .and(not(hasItems(CORRUPTED, CORRUPTED_2)));
}

Entity Driven Testing (EDT) is an approach that implies utilizing Business Entities instead of unnamed test data in the test scenarios.

EDT can be organically combined with Data Driven Testing that uses Business Entities as input with similar scenarios.

JDI Light natively supports EDT with Form, Table and DataList. See the examples in the right panel:

Example scenario:

> Provide List<User> for test
0. Check that there is a user in the database
1. Log in with user data
2. Submit user data in Contact Us form
3. Get actual opening from vacancy table
4. Assert that actual opening equals to expected opening

Code example:

@Test(dataProvider = “users")                      //>
public void formTest(User user) {
    DB.users.shouldHave(user);                     //0.
    loginForm.loginAs(user);                       //1.
    contactUsForm.submit(user);                    //2.
    Vacancy vacancy = vacancyTable.getEntity(3);   //3.
    Assert.areEquals(vacancy, expectedVacancy);    //4.
}

Smart Locators

Smart locators example

Let's assume you have a uniform method to locate most of the elements (for example, most of the elements involved in UI test automation have a predictable id, or a name, or a special attribute used to locate them.)

Let's assume you have @UI("[ui=last-name]") public TextField lastName element in JDI. In this case you can simplify it to public TextField lastName and omit the locator.

Now for more complex example. Suppose you have the following HTML:

<input type="text" ui="name"/>
<input type="text" ui="last-name"/>
<input type="text" ui="pin-code"/>
<input type="text" ui="promo-code"/>
<input type="checkbox" ui="accept-conditions"/>
<a href="..." ui="external-link">External link</a>
<button ui="submit-button">
public class UserCard : Form<User>
{
    [FindBy(Css = "#name")] public TextField Name;
    [FindBy(Css = "#last-name")] public TextField LastName;
    [FindBy(Css = "#submit-button")] public Button SubmitButton;
}
SmartSearchLocator = "#{0}";
SmartSearchName(string name) => StringExtensions.SplitHyphen(name);
public class UserCard : Form<User>
{
    TextField name; 
    TextField LastName;
    Button SubmitButton;
}
@FindBy(css = "[ui=name]") 
public WebElement name;
@FindBy(css = "[ui=last-name]") 
public WebElement lastName;
@FindBy(css = "[ui=pin-ncodeame]") 
public WebElement pinCode;
@FindBy(css = "[ui=promo-code]") 
public WebElement promoCode;
@FindBy(css = "[ui=accept-conditions]") 
public WebElement acceptConditions;
@FindBy(css = "[ui=submit-button]") 
public WebElement submitButton; 

With pure Selenium, Page Object elements for that will look like this:








@UI("[ui=name]") public Textfield name;
@UI("[ui=last-name]") public Textfield lastName;
@UI("[ui=pin-code]") public Textfield pinCode;
@UI("[ui=promo-code]") public Textfield promoCode;
@UI("[ui=accept-conditions]") public Checkbox acceptConditions;
@UI("[ui=submit-button]") public Button submitButton;

In JDI Light with standard UI Objects the code gets more descriptive, but there still are duplications in locator and element names:





public Textfield name, lastName, pinCode, promoCode;
public Checkbox acceptConditions;
public Button submitButton;

But by using smart locators you can write this without any duplications (without locators) in just a few lines. Looks cool, doesn't it?

Define smart locator using test.properties

smart.locators="[ui=%s]"
smart.locators.toName=UPPER_SNAKE_CASE

You can set up your smart locators in the test.properties file the following way.

First, assign a value to the smart.locators property:

Then, assign a value to the smart.toName property. Suppose that you have set smart.locators to [ui=%s]:

...or, if the property looks like smart.locators=//*[text()='%s']:

Define a Smart Locator using WebSettings

WebSettings.SMART_SEARCH_LOCATORS = asList("#%s");
WebSettings.SMART_SEARCH_NAME = StringUtils::toKebabCase;
// JDI Light style
WebSettings.SMART_SEARCH = el -> {
  String locatorName = toKebabCase(el.getName());
  UIElement element = $("[auto="+locatorName+"]", el.base().parent));
  element.setName(el.getName());
  return element.getWebElement();
}
// Selenium style
WebSettings.SMART_SEARCH = el -> {
  String locatorName = toKebabCase(el.getName());
  return getDriver.findElement(By.cssClass("[auto="+locatorName+"]"));
}

You can also set up Smart Locators in code using WebSettings.SMART_SEARCH_NAME and WebSettings.SMART_SEARCH_LOCATORS variables:

Or you can define by yourself what should be done when UI Element has no locator using WebSettings.SMART_SEARCH.









Smart Annotations

When your locators follow standard patterns you can use Smart Annotations to mark elements:

For @UI("#last-name") TextField lastName;
use @SId TextField lastName;

For @UI(".contact-form") Form<CardData> contactForm;
use @SClass Form<CardData> contactForm;

For @UI("//*[text()='Submit Card']") Button submitCard;
use @SText Button submitCard;

For @UI("[name='accept-conditions']") Checkbox acceptConditions;
use @SName Checkbox acceptConditions;

Or use @Smart annotation for any specific HTML attribute:

For @UI("[data-type=data-multi-combobox]") MultiCombobox dataMultiCombobox;
use @Smart("data-type") MultiCombobox dataMultiCombobox;

Custom Smart Annotations

You can also always create your own annotation enabling smart behavior.

Let's assume you would like to use smart locators for buttons like //button[text()='Button Text'].

First, create a new annotation:

SButton.java
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD})
public @interface SButton {
}

Then set up the behavior for this annotation before you call initSite:

@BeforeSuite(alwaysRun = true)
public static void setUp() {
    JDI_ANNOTATIONS.add("Buttons", aRule(SButton.class,
        (e, a) -> e.setLocator(format("//button[text()='%s']", splitCamelCase(e.getName())))));
    initSite(YourAwesomeSite.class);

That's all. Now we can write:

@SButton public Button logIn, signIn, cancel, useVipAccess;

Instead of:

@FindBy(xpath = "//button[text()='Log In']")
public WebElement logIn;
@FindBy(xpath = "//button[text()='Sign In']")
public WebElement signIn;
@FindBy(xpath = "//button[text()='Cancel']")
public WebElement cancel;
@FindBy(xpath = "//button[text()='Use Vip Access']")
public WebElement useVipAccess;

JDI Annotations

In order to control element behavior in JDI Light you can use the following standard annotations:

@Root — ignores all parent sections locators for this element and uses only locator that specified for element (including smart locators).

@Frame("frame-id") or @Frame({"frame-id", "div[name-adv]"}) — in case you have two or more frames above the element, use driver.switchTo().frame(...) before searching your element. Or call it multiple times if @Frame has list of locators. Can be used together with @UI locator.

@Css("div.dropdown") — if your element has a CSS locator (deprecated, recommended to use universal @UI locator instead.)

@XPath("//div[text()='Submit']") — if your element has an XPath locator (deprecated, recommended to use universal @UI locator instead.)

@ByText("Submit") — used to locate elements by text (uses locator ".//*/text()[normalize-space(.) = %s]/parent::*".)

@WithText("Navigation") — used to locate elements by text containing given substring (uses locator ".//*/text()[contains(normalize-space(.), %s)]/parent::*")

@ClickArea(...) — specifies how click will be performed. Allowed values: SMART_CLICK (tries to find area where user able to click), TOP_LEFT (click top left corner of the element), TOP_RIGHT (click top right corner of the element), BOTTOM_LEFT (click bottom left corner of the element), BOTTOM_RIGHT (click bottom right corner of the element), CENTER (standard Selenium click in the center of the element), JS (using JS click).

@GetTextAs(...) — specifies how getText will be performed. Allowed values: TEXT (getText()), VALUE (getAttribute("value")), INNER (jsExecute("innerText")), LABEL (using a label related to the element; good for checkboxes and radio buttons), SMART_TEXT (tries smart value search).

@SetTextAs(...) — specifies how text input will be performed. Allowed values: SEND_KEYS (sendKeys(...)), SET_TEXT (set value attribute using JS), CLEAR_SEND_KEYS (clear() then sendKeys(...)).

@NoCache — always get the element from the page. Do not use cache.

@WaitTimeout(sec) — set sec seconds implicit wait for the element.

@NoWait — no element wait timeout; the element won't be found unless it's present on the page.

@Name(“Test”) — sets the name of an element to the provided value.

@GetAny — gets element without validation.

@GetVisible — returns displayed element.

@GetVisibleEnabled — returns displayed and enabled element.

@GetShowInView — returns displayed and clickable element.

@PageName — sets pageName variable for the element.

@SId — sets smart ID locator, e.g “By.cssSelector: #Test”, where “Test” is the element's id attribute.

@SText — sets smart text locator, e.g. “By.xpath: .//*/text()[normalize-space(.) = "S Text"]/parent::*”, where “SText” is the name of the element. Be aware that it’s creating a locator with white space for words starting with capital letter.

@SName — sets smart name locator, e.g. for “@Name(“Test”) @SName” it will be “By.cssSelector: [name='test']”.

@Smart — sets smart locator, e.g. for “@Name(“Smart”) @Smart(“id”)” it will be “By.cssSelector: [id=’smart’]”.

@SClass — sets smart class locator, e.g. for “@Name(“Test”) @SName” it will be “By.cssSelector: .test”.

@UI — for list UI locator, e.g. @UI("img"), see more examples in the previous section.

@FindBy — an annotation that can have attributes such as: css, tagName, linkText, partialLinkText, xpath; text, id, name, className, group. Could be quickly changed to from Selenium @FindBy by changing the import line.

@VisualCheck — adds the “(“visualCheck”, “”)” pair to params.

JDI Locators (as simple as CSS, as powerful as XPath)

@XPath("//div[contains(@class,'btn')]//*[text()='Submit']")
@UI("div.btn['Submit']")

@XPath("//*[contains(@class,'nav-menu')]//*[@data-role='header']//*[contains(text(),'Navigation menu')]")
@UI(".nav-menu [data-role=header][*'Navigation menu']")

@XPath("//label[text()='Gold status']/..//input[@type='checkbox']")
@UI("label['Gold status']<input[type=checkbox]")

@XPath("//*[contains(@class,'nav-menu')]//*[@data-role='header'][3]")
@UI(".nav-menu [data-role=header][3]")

With JDI Light you can use simple and fast CSS-like selectors with the power of XPath locators. Now you can search by text or index with CSS-like syntax or even move up the DOM tree.

See some examples below:

XPath: //div[contains(@class,'btn')]//*[text()='Submit']
JDI Locator: div.btn['Submit']

XPath: //*[contains(@class,'nav-menu')]//*[@data-role='header']//*[contains(text(),'Navigation menu')]
JDI Locator: .nav-menu [data-role=header][*'Navigation menu']

XPath: //label[text()='Gold status']/..//input[@type='checkbox']
JDI Locator: label['Gold status']<input[type=checkbox]

XPath: //*[contains(@class,'nav-menu')]//*[@data-role='header'][3]
JDI Locator: .nav-menu [data-role=header][3]

FAQ

TBD

Documentation

Base information

Base Elements

UIBaseElement

UIElement


  @Test
  public void click() {
      submit.click();
      assertEquals(sum.getText(), "Summary: 3");
  }

  @Test
  public void isDisplayed(){
      assertTrue(submit.isDisplayed());
  }

  @Test
  public void input(){
      description.input("Hello world!");
      assertEquals(description.getText(), "Hello world!");
      description.clear();
  }

  @Test
  public void hasAttribute() {
      assertTrue(submit.hasAttribute("class"));
      assertTrue(submit.hasAttribute("type"));
  }

Available methods in Java JDI Light:

Method Description Return Type
check() Clicks on element if it's not selected void
classes() Gets all element's classes as list List
clear() Clears input field void
click() Clicks on element void
click(ElementArea area) Clicks on element area (possible ElementArea values are SMART_CLICK, TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT, CENTER, JS) void
click(int x, int y) Clicks on point (x, y) void
doubleClick() Double clicks on the element void
dragAndDropTo(int x, int y) Drags and drops element to certain coordinates void
dragAndDropTo(WebElement to) Drags and drops element to another element void
focus() Focuses on element void
getAllAttributes() Gets all element attributes MapArray
getAttribute(String value) Gets the value of specified element attribute String
getCssValue(String value) Gets element CSS value String
getLocation() Gets element location as point Point
getRect() Gets element rectangle Rectangle
getSize() Gets element size Dimension
getTagName() Gets element tag name String
getText() Gets element text String
getValue() Gets element text String
hasAttribute(String attrName) Returns true if the element has an expected attribute boolean
hasClass(String className) Returns true if the element has an expected class boolean
highlight() Highlights element with red color void
highlight(String color) Scrolls view to element and highlights it with a border of specified color void
hover() Hovers mouse cursor over the element void
input(String value) Inputs specified value as keys void
isDeselected() Checks that element is deselected boolean
isDisabled() Checks that element is disabled boolean
isDisplayed() Checks that element is displayed boolean
isEnabled() Checks that element exists boolean
isHidden() Checks that element is hidden boolean
isNotExist() Checks that element does not exist boolean
isNotVisible() Checks that element is not visible by user boolean
isSelected() Checks that element is selected boolean
isVisible() Checks that element is visible by user boolean
jsExecute(String jsCode) Executes JavaScript code String
labelText() Gets label text String
makePhoto() Gets a screenshot of the element File
placeholder() Gets element “placeholder” attribute value String
printHtml() Gets element “innerHTML” attribute value String
rightClick() Right clicks on the element void
select() Selects item void
select(int index) Selects item by index void
select(String value) Selects item by value void
select(String… names) Selects items by values void
sendKeys(CharSequence… value) Sends specified value as keys void
setAttribute(String name, String value) Sets value to the specified attribute void
setText(String value) Puts value as text void
setValue() Inputs value void
show() Scrolls screen view to item void
uncheck() Clicks on element if selected void

Aliases in Java JDI Light:

Method Description Return Type
attr(String value) Gets element attribute String
attrs() Gets all element attributes MapArray
css(String prop) Gets element css value String
text() Gets element text String

WebList

Extended Selenium features

Wait After Action

You can annotate a UI element with @WaitAfterAction. This tells JDI to wait after executing this element's methods.

@WaitAfterAction(value = 3, method = "getText") would mean that JDI will wait 3 seconds after executing the annotated element's getText() method.

If the method name is not specified, the wait will be applied to all action methods of the element (like click, check or select, depending on the element), and you can write the annotation like @WaitAfterAction(3).

You can also apply the default @WaitAfterAction which sets the wait to 1 second for all action methods.

   @WaitAfterAction(value = 3, method = "getText")
   public Text colorValue;

   @WaitAfterAction(2)
   public Dropdown detailsButton;

   @WaitAfterAction
   public Dropdown colors;

   ...  

   @Test
   public void selectColor() {
     detailsButton.click()  // will wait 2 seconds after click
     colors.select("Gold");  // will wait 1 second after select 
     assertEquals(colorValue.getText(), "Gold") // will wait 3 seconds after getText 
   }

1. HTML5 elements

1.1 HTML5 Common elements

1.1.1 Label

  // @FindBy(xpath = "//label[@for='your-name']")
  @UI("//label[@for='your-name']") 

  public static TextField yourName;

  @Test
  public void labelTest() {
      assertEquals(yourName.label().getText(), "Your name:");
      yourName.label().is().text(containsString("Your"));
      disabledName.label().is().text(equalToIgnoringCase("Surname:"));
  }

 In the next test Label is found from NameTextField locator:

 [FindBy(Css = "div.main-content #name")]
 public TextField NameTextField { get; set; }

 By default, Label is found by locator By.CssSelector($"[for={WebElement.GetAttribute("id")}]")

 [Test] 
 public void LabelTest() 
 { 
     Assert.AreEqual(TestSite.Html5Page.NameTextField.Label().GetText(), "Your name:");
     TestSite.Html5Page.NameTextField.Label().Is.Text(ContainsString("Your"));
     Assert.AreEqual(TestSite.Html5Page.SurnameTextField.Label().GetText(), "Surname:");
     TestSite.Html5Page.SurnameTextField.Label().Is.Text(ContainsString("Surname:")); 
 }   

 [Test] 
 public void GetLabelTextTest() 
 { 
     AreEqual(TestSite.Html5Page.ColorPicker.LabelText(), "Select a color"); 
 } 

Label — Defines a label for an <input> control.

Label

<form>
    <input type="radio" name="gender" value="male" id="male">
    <label for="male">Male</label>
    <input type="radio" name="gender" value="female" id="female">
    <label for="female">Female</label>
</form>

Available methods in JDI Light:

Method Description Return Type
setValue(String) sets value void
getValue() gets value String
getText() returns value. Overrided method of UIBaseElement String
is() Assert action TextAssert

Available methods in C# JDI Light:

Method Description Return Type
assertThat() Assert action TextAssert
click() Click the button void
getText() Get button text String
is() Assert action TextAssert
Label() Creates label for element using the element's Id Label
LabelText() Gets the text of a label string

Java test examples

C# test examples

BDD Steps examples

1.1.2 Button

@UI("[value*='Red Button']") 
// @FindBy(css = "[value*='Red Button']")
public static Button redButton;

@Test
public void clickTest() {
    redButton.click();
    validateAndAcceptAlert("Red button");

    blueButton.click();
    validateAndAcceptAlert("Blue button");
}

[FindBy(Css = ".red")]
public Button RedButton;

[Test]
public void ClickTest() 
{
    RedButton.Click();
    Assert.AreEqual(GetAlert().GetAlertText(), "Red button");
    GetAlert().AcceptAlert();
}

[Test]
public void GetTextTest() 
{
    Assert.AreEqual(RedButton.GetText(), "Big Red Button-Input");
}

Button — The <button> tag is used to create clickable buttons on the web page

Button

Here is an example with provided HTML code: html <input type="button" value="Big Red Button-Input" class="uui-button red" onclick="alert('Red button');">

Button is located in the following classes:

Available methods in Java JDI Light:

Method Description Return Type
getValue() Get button's value String
is() Assert action TextAssert

Available methods and properties in C# JDI Light:

Method/Property Description Return Type
AssertThat Assert action TextAssert
Click() Click the button void
GetText() Get button text string
Is Assert action TextAssert

Java test examples
C# test examples
BDD Steps example

1.1.3 Checkbox

Checkbox — Element allows you to select a single value for submission.

Checkbox

Checkbox is located in the following classes:

Here is an example with provided HTML code:

//@FindBy(xpath = "//input[@type='checkbox' and @id='accept-conditions']") 
@UI("//input[@type='checkbox' and @id='accept-conditions']")
public static Checkbox acceptConditions;

@Test
public void checkTest() {
    acceptConditions.check();
    acceptConditions.is().selected();
}

@Test
public void uncheckTest() {
    acceptConditions.uncheck();
    acceptConditions.is().deselected();
}

@Test
public void getLabelTextTest() {
    acceptConditions.label().is().text(labelText);
}

[FindBy(XPath = "//*[@id='elements-checklist']//*[text()='Water']")]
[IsChecked(typeof(CustomCheck), nameof(CustomCheck.CheckFunc))]
public CheckBox CbWater;

[FindBy(Css = "#accept-conditions")]
public CheckBox AcceptConditions { get; set; }

[Test]
public void CheckSingleTest()
{
     Assert.DoesNotThrow(() => TestSite.MetalsColorsPage.CbWater.Check(true));
     Jdi.Assert.Contains(TestSite.ActionsLog.Texts[0], "Water: condition changed to true");
}

[Test]
public void UncheckSingleTest()
{
     TestSite.MetalsColorsPage.CbWater.Click();
     TestSite.MetalsColorsPage.CbWater.Uncheck();
     Jdi.Assert.Contains(TestSite.ActionsLog.Texts[0], "Water: condition changed to false");
}

[Test]
public void IsCheckTest()
{
     Assert.IsFalse(TestSite.MetalsColorsPage.CbWater.IsChecked);
     TestSite.MetalsColorsPage.CbWater.Click();
     Assert.IsTrue(TestSite.MetalsColorsPage.CbWater.IsChecked);
}

[Test]
public void MultipleUncheckTest()
{
     TestSite.MetalsColorsPage.CbWater.Click();
     TestSite.MetalsColorsPage.CbWater.Uncheck();
     TestSite.MetalsColorsPage.CbWater.Uncheck();
     Jdi.Assert.Contains(TestSite.ActionsLog.Texts[0], "Water: condition changed to false");
}

[Test]
public void ClickTest()
{
     TestSite.MetalsColorsPage.CbWater.Click();
     Jdi.Assert.Contains(TestSite.ActionsLog.Texts[0], "Water: condition changed to true");
     TestSite.MetalsColorsPage.CbWater.Click();
     var texts = TestSite.ActionsLog.Texts;
     Jdi.Assert.Contains(texts[0], "Water: condition changed to false");
}

[Test]
[TestCaseSource(typeof(CheckBoxProvider), nameof(CheckBoxProvider.InputData))]
public void SetValueTest(bool value, bool expected)
{
     if (!expected) TestSite.MetalsColorsPage.CbWater.Click();
     TestSite.MetalsColorsPage.CbWater.Value = value;
     var resultMsg = "Water: condition changed to " + expected.ToString().ToLower();
     Jdi.Assert.Contains(TestSite.ActionsLog.Texts[0], resultMsg);
}

[Test]
public void IsValidationTest()
{
    TestSite.Html5Page.Open();
    TestSite.Html5Page.AcceptConditions.Is.Selected();
    TestSite.Html5Page.AcceptConditions.Click();
    TestSite.Html5Page.AcceptConditions.Is.Deselected();
    TestSite.Html5Page.AcceptConditions.Is.Enabled();
    TestSite.Html5Page.AcceptConditions.Is.Displayed();
}

[Test]
public void LabelTest()
{
    TestSite.Html5Page.Open();
    Assert.AreEqual("Accept terms and conditions", TestSite.Html5Page.AcceptConditions.Label().GetText());
    TestSite.Html5Page.AcceptConditions.Label().Is.Text(ContainsString("terms and conditions"));
    TestSite.Html5Page.AcceptConditions.Label().Is.Text(EqualTo("accept terms and conditions"));
}

[Test]
public void AssertValidationTest()
{
    TestSite.Html5Page.Open();
    TestSite.Html5Page.AcceptConditions.AssertThat.Selected();
}

[Test]
public void BaseValidationTest()
{
    TestSite.Html5Page.Open();
    BaseElementValidation(TestSite.Html5Page.AcceptConditions);
}

<div>
  <input type="checkbox" id="accept-conditions" checked="">
  <label for="accept-conditions">Accept terms and conditions</label>
</div>

Available methods in Java JDI Light:

Method Description Return Type
safeGetLabel() Safely returns label Label
check(String) Set to checked if string value equals "true" (case insensitive), otherwise set to unchecked void
check() Set to checked void
uncheck() Set to unchecked void

Available methods in C# JDI Light:

Method Description Return Type
AssertThat Gets assert for checkbox CheckBoxAssert
Check(bool checkEnabled = true) Checks a checkbox void
Deselected() Checks whether a checkbox is deselected CheckBoxAssert
Displayed() Checks whether a checkbox is displayed CheckBoxAssert
Enabled() Checks whether a checkbox is enabled CheckBoxAssert
Is Gets assert for checkbox CheckBoxAssert
IsChecked Determines whether a checkbox is checked bool
Selected() Checks whether a checkbox is selected CheckBoxAssert
Uncheck(bool checkEnabled = true) Unhecks a checkbox void

Java test examples

C# test examples

BDD Steps example

1.1.4 ColorPicker

//@FindBy(xpath = "//input[@type='color' and @id='color-picker']") 
@UI("//input[@type='color' and @id='color-picker']")
public static ColorPicker colorPicker;

@Test
public void getColorTest() {
    assertEquals(disabledPicker.color(), defaultColor);
}
@Test
public void setColorTest() {
    colorPicker.setColor("#432376");
    assertEquals(colorPicker.color(), "#432376");
    disabledPicker.setColor("#432376");
    assertEquals(disabledPicker.color(), "#432376");
}
[FindBy(Css = "#color-picker")]
public ColorPicker ColorPicker;

[Test]
public void GetColorTest() 
{
    Assert.AreEqual(ColorPicker.Color(), "#3fd7a6");
}

[Test]
public void SetColorTest() 
{
    ColorPicker.SetColor("#432376");
    Assert.AreEqual(ColorPicker.Color(), "#432376");
}

ColorPicker — Elements of this type provide a user interface element that lets a user specify a color, either by using a visual color picker interface or by entering the color into a text field in "#rrggbb" hexadecimal format. Only simple colors (with no alpha channel) are allowed. The values are compatible with CSS.

ColorPicker

Color Picker is located in the following classes:

Here is an example with provided HTML code:

<div>
  <input type="color" value="#3fd7a6" id="color-picker">
  <label for="color-picker">Select a color</label>
</div>

Here is the list of some available methods in Java:

Methods Description Return Type
color() Returns color code in hexadecimal format ("#rrggbb") String
setColor(String) Set color from string hex representation ("#rrggbb") void

Here is the list of some available methods in C#:

Methods Description Return Type
AssertThat() Assert action ColorAssert
Color() Returns color code in hexadecimal format ("#rrggbb") string
Is() Assert action ColorAssert
SetColor(String) Set color from string hex representation ("#rrggbb") void

Java test examp
Test examples in C#
BDD Steps example

1.1.5 DateTimeSelector

DateTimeSelector — Is used for Input Type Date and its derivatives and allows users to set the value of date and/or time.

The list of supported elements:


Input Type Date — A graphical control element that allows user to set value for date.

//@FindBy(css = "#birth-date")
@UI("#birth-date")

public static DateTimeSelector birthDate;

@Test
public void setDateTimeTest() {
    birthDate.setDateTime("2018-11-13");
    assertEquals(birthDate.value(), "2018-11-13");
}

@Test
public void labelTest() {
    assertEquals(birthDate.label().getText(), "Birth date");
    birthDate.label().is().text(containsString("Birth"));
}
[FindBy(Css = "#birth-date")]
public IDateTimeSelector BirthDate { get; set; }

[Test]
public void SetBirthDateTest()
{
    TestSite.Html5Page.BirthDate.Format = "yyyy-MM-dd";
    TestSite.Html5Page.BirthDate.SetDateTime(_dateTime);    
    TestSite.Html5Page.BirthDate.AssertThat().SelectedTime(Is.EqualToIgnoringCase("2019-04-01"));   
}

InputTypeDate

<div>
  <label for="birth-date">Birth date</label>
  <input type="date" id="birth-date" value="1985-06-18" min="1970-01-01" max="2030-12-31">
</div>

Type Date test examples in Java
Type Date test examples in C#


Input Type Week — A graphical control element that allows user to set values for week and year.

//@FindBy(css = "#autumn-week")
@UI("#autumn-week")

public static DateTimeSelector autumnWeek;

@Test
public void setDateTimeTest() {
    autumnWeek.setDateTime("2018-W12");
    autumnWeek.show();
    assertEquals(autumnWeek.value(), "2018-W12");
}

@Test
public void labelTest() {
    autumnWeek.label().assertThat().text(is("Autumn"));
    autumnWeek.label().is().text(equalToIgnoringCase("autumn"));
}
[FindBy(Css = "#autumn-week")]
public IDateTimeSelector AutumnDateTime { get; set; }

[Test]
public void AutumnDateTimeTest()
{
    var calendar = new GregorianCalendar();
    var weekNum = calendar.GetWeekOfYear(_dateTime, CalendarWeekRule.FirstFullWeek, DayOfWeek.Monday);
    TestSite.Html5Page.AutumnDateTime.Format = "yyyy-" + $"W{weekNum}";

    TestSite.Html5Page.AutumnDateTime.SetDateTime(_dateTime);
    var setValue = TestSite.Html5Page.AutumnDateTime.GetValue();
    Assert.AreEqual(setValue, "2019-W13");
}

InputTypeWeek

<div>
  <label for="autumn-week">Autumn</label>
  <input type="week" id="autumn-week" value="2018-W40" min="2018-W35" max="2018-W48" required="">
</div>

Type Week test examples in Java
Type Week test examples in C#


Input Type Month — a graphical control element that allows user to set values for month and year.

//@FindBy(css = "#month-date")
@UI("#month-date")

public static DateTimeSelector monthDate;

@Test
public void setDateTimeTest() {
    monthDate.setDateTime("2018-10");
    monthDate.show();
    assertEquals(monthDate.value(), "2018-10");
}

@Test
public void labelTest() {
    monthDate.label().is().text(containsString("Holidays"));
    monthDate.label().is().text(equalToIgnoringCase("month of holidays"));
}
[FindBy(Css = "#month-date")]
public IDateTimeSelector MonthOfHolidays { get; set; }

[Test]
public void SetMonthTest()
{
    TestSite.Html5Page.MonthOfHolidays.Format = "yyyy-MM";
    TestSite.Html5Page.MonthOfHolidays.SetDateTime(_dateTime);
    var setValue = TestSite.Html5Page.MonthOfHolidays.GetValue();
    Assert.AreEqual(setValue, "2019-04");
}

InputTypeMonth

<div>
  <label for="autumn-week">Autumn</label>
  <input type="week" id="autumn-week" value="2018-W40" min="2018-W35" max="2018-W48" required="">
</div>

Type Month test examples in C#

Type Month test examples in Java


Input Type Time — A graphical control element that allows user to set time.

//@FindBy(css = "#booking-time")
@UI("#booking-time")

public static DateTimeSelector bookingTime

@Test
public void setDateTimeTest() {
    bookingTime.setDateTime("05:00");
    bookingTime.show();
    assertEquals(bookingTime.value(), "05:00");
}

@Test
public void labelTest() {
    assertEquals(bookingTime.label().getText(), "Booking Time:");
    bookingTime.label().is().text(equalToIgnoringCase("booking Time:"));
}
[FindBy(Css = "#booking-time")]
public IDateTimeSelector BookingTime { get; set; }

[Test]
public void SetTimeTest()
{
    TestSite.Html5Page.BookingTime.Format = "H:mm";
    TestSite.Html5Page.BookingTime.SetDateTime(_dateTime);
    var setValue = TestSite.Html5Page.BookingTime.GetValue();
    Assert.AreEqual(setValue, "15:00");
}

InputTypeTime

<div>
  <label for="booking-time">Booking Time:</label>
  <input type="time" id="booking-time" value="11:00" min="9:00" max="18:00">
</div>

Type Time test examples in C#
Type Time test examples in Java


Input Type DateTime-Local — A graphical control element that allows user to set time and date.

//@FindBy(css = "#party-time")
@UI("#party-time")

public static DateTimeSelector partyTime;

@Test
public void setDateTimeTest() {
    partyTime.setDateTime("2017-05-10T00:00");
    partyTime.show();
    assertEquals(partyTime.value(), "2017-05-10T00:00");
}

@Test
public void labelTest() {
    partyTime.label().assertThat().text(is("Date/time:"));
    partyTime.label().is().text(equalToIgnoringCase("date/time:"));
}
[FindBy(Css = "#party-time")]
public IDateTimeSelector PartyTime { get; set; }

[Test]
public void SetPartyTimeTest()
{
    TestSite.Html5Page.PartyTime.Format = "yyyy-MM-ddTHH:mm";
    TestSite.Html5Page.PartyTime.SetDateTime(_dateTime);
    var setValue = TestSite.Html5Page.PartyTime.GetDateTime();
    Assert.AreEqual(setValue, _dateTime);
}

InputTypeDateTime

<div>
  <label for="party-time">Date/time:</label>
  <input type="datetime-local" id="party-time" value="2018-06-12T19:30" min="2018-05-07T00:00" max="2018-06-14T00:00">
</div>

Type DateTime-Local test examples in Java
Type DateTime-Local test examples in C#

There following classes represent this type of element:

Here is the list of some methods available in C#:

Method Description Return Type
AssertThat() Assert action of DateTimeSelector DateTimeSelectorAssert
GetDateTime() Returns the set date or time DateTime
Is() Assert action of DateTimeSelector DateTimeSelectorAssert
Max() Gets attribute with name 'max' string
Min() Gets attribute with name 'min' string
SetDateTime(string/DateTime value) Sets a date or time void
Value() Returns value attribute string

And here are some of the methods available in Java:

Method Description Return Type
value() Returns the set date or time String
max() Gets attribute with name max String
min() Gets attribute with name min String
setDateTime(String) Sets a date or time void
setValue(String) Sets a date or time void
getValue() Returns the set date or time String
is() Assertion DateTimeAssert

BDD Steps example

In the following sections there are examples of different implementations of such fields.

1.1.6 FileInput

FileInput — A graphical control element that allows user to upload documents to web site.

//@FindBy(id = "avatar")
@UI("#avatar") 
public static FileInput avatar; 

@Test
public void uploadTest() {
    avatar.uploadFile(mergePath(COMMON.projectPath,"/src/test/resources/functional.xml"));
    avatar.is().text(containsString("functional.xml"));
    assertTrue(avatar.getText().contains("functional.xml"));
    assertTrue(avatar.getValue().contains("functional.xml"));
}

@Test
public void labelTest() {
    assertEquals(avatar.labelText(), "Profile picture:");
    avatar.label().is().text(containsString("picture"));
}
[Test]
public void FileInputTest()
{
    FileInput.SelectFile(CreateFile(filename));
}

[Test]
public void DisabledUploadTest()
{
    Sleep(2000);
    try
    {
         TestSite.Html5Page.DisabledFileInput.SelectFile(CreateFile(_fileName));
    }
    catch (Exception e)
    {
         Logger.Exception(e);
    }
    Sleep(2000);
    TestSite.Html5Page.DisabledFileInput.Is.Text(EqualTo(""));
}

[Test]
public void LabelTest()
{
    AreEqual(TestSite.Html5Page.FileInput.LabelText(), "Profile picture:");
    TestSite.Html5Page.FileInput.Label().Is.Text(ContainsString("picture"));
}

[Test]
public void BaseValidationTest()
{
    BaseElementValidation(TestSite.Html5Page.FileInput);
}

FileInput

FileInput element is located in JDI Light in:

Here is an example with HTML code provided:

<div class="html-left">
  <label for="avatar">Profile picture:</label>
  <input type="file" id="avatar" accept="image/png, image/jpeg">
</div>

Available method in Java JDI Light:

Method Description Return Type
uploadFile(String) set file path to input void
uploadFileRobot(String, long) set file path to input void
setValue(String) set file path to input void
text() returns text of input field String
getValue() Get file name String
is() property that returns object for work with assertions TextAssert

Available method in C# JDI Light:

Method Description Return Type
CleanupDownloads() Cleans the directory void
HasSize(Matcher size) Checks that a file has a particular size according to the matcher FileAssert
IsDownloaded() Checks whether a file is downloaded FileAssert
SelectFile(string filepath) Select file to upload void
Text(Matcher value) Checks whether an occurrence of a text is contained within a text file FileAssert

Test examples in Java
Test examples in C#
BDD Steps example

1.1.7 Icon

Icon — Is a simple element type that represents icons and graphic images.

Icon

  @UI("#jdi-logo") 
  // same as FindBy(css = "#jdi-logo")
  public static Icon userIcon;

  @Test
  public void loginWithUserToLightLocatorFormTest() {
      userIcon.click();
      loginAs("#login-form", DEFAULT_USER);
      homePage.checkOpened();
  }
  [FindBy(Css = "#jdi-logo")]
  public IIcon Logo
  ;

  [Test]
  public void GetSourceTest()
  {
    Jdi.Assert.AreEquals(LogoImage.GetSource(), Src);
  }

  [Test]
  public void GetTipTest()
  {
    Jdi.Assert.AreEquals(LogoImage.GetAlt(), Alt);
  }
<label for="jdi-logo">JDI Logo:</label>
<img src="/jdi-light/images/jdi-logo.jpg" id="jdi-logo" alt="Jdi Logo 2"
     width="101" height="100" onclick="alert('JDI Logo');">

Test examples in Java

Icon is represented by Image class:

Image

Icon in JDI is a descendant of Image. It inherits all Image's methods and serves as its wrapper. Here are Java methods for Icon, inherited from Image interface:

Method Description Return Type
alt() get value of alt attribute String
click() click on the image void
height() get value of height attribute int
is() method for building assertions ImageAssert
src() get value of src attribute String
width() get value of width attribute int
fileName() Get image source path String
getValue() Get image source path String

Here is a list of available methods in C#:

Method Description Return Type
Alt get value of alt attribute string
AssertThat() method for building assertions ImageAssert
Click() click on the image void
Height get value of height attribute string
Is() method for building assertions ImageAssert
Src get value of src attribute string
Width get value of width attribute string

Test examples in Java

Test examples in C#

BDD Steps example

1.1.8 Image

Image — Is a simple element type that represents graphic images.

Image

  @UI("#jdi-logo") 
  // same as FindBy(css = "#jdi-logo")
  public static Image jdiLogo;

  @Test
  public void isValidationTest() {
      WebPage.refresh();
      jdiLogo.is().src(containsString("jdi-logo.jpg"));
      jdiLogo.is().alt(is("Jdi Logo 2"));
      jdiLogo.assertThat().height(is(100));
      jdiLogo.assertThat().width(is(101));
  }

  @Test
  public void getSrcTest() {
      assertEquals(jdiLogo.src(), text);
  }
  [FindBy(Css = "#jdi-logo")]
  public IImage LogoImage;

  [Test]
  public void GetSourceTest()
  {
    Jdi.Assert.AreEquals(LogoImage.GetSource(), Src);
  }

  [Test]
  public void GetTipTest()
  {
    Jdi.Assert.AreEquals(LogoImage.GetAlt(), Alt);
  }
<label for="jdi-logo">JDI Logo:</label>
<img src="/jdi-light/images/jdi-logo.jpg" id="jdi-logo" alt="Jdi Logo 2" 
     width="101" height="100" onclick="alert('JDI Logo');">

Images are represented by the following classes in Java and C#:

Here is a list of available methods in Java:

Method Description Return Type
alt() get value of alt attribute String
click() click on the image void
height() get value of height attribute int
is() method for building assertions ImageAssert
src() get value of src attribute String
width() get value of width attribute int
fileName() Get image source path String
getValue() Get image source path String

Test examples in Java

Here is a list of available methods in C#:

Method Description Return Type
Alt get value of alt attribute string
AssertThat() method for building assertions ImageAssert
Click() click on the image void
Height get value of height attribute string
Is() method for building assertions ImageAssert
Src get value of src attribute string
Width get value of width attribute string

Test examples in C#


  //@FindBy(css = "[ui=github-link]") 
  @UI("[ui=github-link]") 
  public static Link githubLink;

  @Test
  public void getTextTest() {
        assertEquals(githubLink.getText(), text);
  }

  @Test
  public void getRefTest() {
        assertEquals(githubLink.ref(), "https://github.com/jdi-testing");
  }
  [FindBy(Css = "[ui = github-link]")]
  public ILink GithubLink;

  [Test]
  public void GetTextTest()
  {
      Assert.AreEqual(GithubLink.GetText(), Text);
  }

  [Test]
  public void GetUrlTest()
  {
       Assert.AreEqual(GithubLink.Url(), "https://epam.github.io/JDI/html5.html");
  }

Link — A graphical control element that allows user to link from one page to other web pages, files, locations within the same page, email addresses, or any other URL.

Link are represented by the following class:

Link

<a ui="github-link" href="https://github.com/jdi-testing" alt="Github JDI Link">Github JDI</a>

Here is the list of available methods in Java:

Method Description Return Type
alt() Returns the alternate text String
click() Follow the link void
getValue() Returns the link text String
is() Returns object for work with assertions LinkAssert
ref() Returns the reference String
url() Returns the URL URL

Test examples in Java
BDD Steps example

Here is the list of available methods in C#:

Method Description Return Type
Alt() Returns the alternate text string
AssertThat() Returns object for work with assertions LinkAssert
Click() Follow the link void
GetText() Returns the link text string
Is() Returns object for work with assertions LinkAssert
Ref() Returns the reference string
Url() Returns the URL string

Test examples in C#
BDD Steps example

1.1.10 Menu

Menu — A list of links which lead to different pages or sections of website.

Menu element is located in JDI Light in:

Menu example

Here is an example with provided HTML code:

  @UI(".sidebar-menu [ui=label]") 
  //@FindBy(css = ".sidebar-menu [ui=label]")
  public static Menu leftMenu;

  @Test
  public void setNullValueTest() {
        String optionName = null;
        String selectedValue = leftMenu.selected();
        leftMenu.select(optionName);
        leftMenu.has().text(selectedValue);
  }

  @Test
  public void selectTest() {
        leftMenu.select("Contact form");
        contactFormPage.checkOpened();
  }

  [FindBy(Css = "ul.sidebar-menu")]
  public Menu SidebarMenu;

  [Test]
  public void SelectEnumTest()
  {
       TestSite.SidebarMenu.Select(Navigation.MetalsColors);
       TestSite.MetalsColorsPage.CheckOpened();
  }

  [Test]
  public void IsValidationTest()
  {
       TestSite.SidebarMenu.Select("Elements packs", "HTML 5");
       TestSite.SidebarMenu.Is.Selected("HTML 5")
  }

  [Test]
  public void AssertValidationTest()
  {
       TestSite.SidebarMenu.Select("Elements packs", "HTML 5");
       TestSite.SidebarMenu.AssertThat.Selected("HTML 5");
  }

<ul class="sidebar-menu left">
    <li ui="label" index="1">
        <a href="index.html">
            <span>Home</span>
        </a>
    </li>
    <li ui="label" index="2">
        <a href="contacts.html">
            <span>Contact form</span>
        </a>
    </li>
    <li class="menu-title" index="3">
        <a ui="label">
            <span>Service</span>
            <div class="fa fa-caret-down arrow"/>
        </a>
        <ul class="sub hide-menu">
            <li ui="label" index="1">
                <a href="support.html">
                    <p>
                        <span>Support</span>
                    </p>
                </a>
            </li>
            <li ui="label" index="2">
                <a href="dates.html">
                    <span>Dates</span>
                </a>
            </li>
            <li ui="label" index="3">
                <a href="complex-table.html">
                    <span>Complex Table </span>
                </a>
            </li>
            <li ui="label" index="4">
                <a href="simple-table.html">
                    <span>Simple Table</span>
                </a>
            </li>
            <li ui="label" index="5">
                <a href="search.html">
                    <span>Search</span>
                </a>
            </li>
            <li ui="label" index="6">
                <a href="user-table.html">
                    <span>User Table</span>
                </a>
            </li>
            <li ui="label" index="7">
                <a href="table-pages.html">
                    <span>Table with pages</span>
                </a>
            </li>
            <li ui="label" index="8">
                <a href="different-elements.html">
                    <span>Different elements</span>
                </a>
            </li>
            <li ui="label" index="9">
                <a href="performance.html">
                    <span>Performance</span>
                </a>
            </li>
        </ul>
    </li>
    <li ui="label" index="4">
        <a href="metals-colors.html">
            <span>Metals &amp; Colors</span>
        </a>
    </li>
    <li class="menu-title active" index="5">
        <a ui="label">
            <span>Elements packs</span>
            <div class="fa fa-caret-down arrow"/>
        </a>
        <ul class="sub">
            <li ui="label" index="1" class="active">
                <a href="html5.html">
                    <span>HTML 5</span>
                </a>
            </li>
            <li ui="label" index="2">
                <a href="mobile-html5.html">
                    <span>Mobile and HTML 5</span>
                </a>
            </li>
            <li ui="label" index="3">
                <a href="bootstrap-new.html">
                    <span>Bootstrap</span>
                </a>
            </li>
            <li ui="label" index="4">
                <a href="bootstrap_form.html">
                    <span>Bootstrap form</span>
                </a>
            </li>
            <li ui="label" index="5">
                <a href="bootstrap_forms.html">
                    <span>Bootstrap forms</span>
                </a>
            </li>
            <li ui="label" index="6">
                <a href="react-ant.html">
                    <span>React Ant</span>
                </a>
            </li>
            <li ui="label" index="7">
                <a href="angular.html">
                    <span>Angular</span>
                </a>
            </li>
            <li ui="label" index="8">
                <a href="material">
                    <span>Material UI</span>
                </a>
            </li>
            <li ui="label" index="9">
                <a href="vuetify">
                    <span>Vuetify</span>
                </a>
            </li>
        </ul>
    </li>
</ul>

Available methods in Java JDI Light:

Method Description Return Type
selected() Returns selected menu item String
selected(String/int) Check is item seleceted boolean
values() Returns selected menu item and subitems List
values(TextTypes) Returns selected menu item and subitems List
select(String/String.../int/int.../TEnum/TEnum...) Select menu element void
listEnabled() Returns all enable menu options List
listDisabled() Returns all disabled menu options List
attrs() Gets all element attributes List
getText() Gets button text String
getValue() Returns the value String
setValue(String) Sets the value void
isDisplayed() Check that menu is displayed boolean
isHidden() Check that menu is hidden boolean
size() Get menu size int
isEmpty() Check that '{name}' menu is empty boolean
isNotEmpty() Check that '{name}' menu is not empty boolean

Available methods in C# JDI Light:

Method Description Return Type
AssertThat Get select assert MenuSelectAssert
Is Get select assert MenuSelectAssert
List Values() Gets values of all options List
string Selected() Returns selected menu item string
void HoverAndClick(string[]) Hovers and clicks menu item and subitems void
void HoverAndClick(string) Hovers and clicks menu item void
void Select(string[]) Select menu element and subelements by string values void
void Select(string) Select menu element void
void Select(int[]) Select menu element and subelements by index void
void Select(int) Select menu element and subelements by index void
void Select(Enum[]) Select menu element and subelements by getting values of enum void
void Select(Enum) Select menu element void

Test examples in Java

Test examples in C#

BDD Steps example

1.1.11 NumberSelector

NumberSelector — A graphical control element that allows the user to enter a number.

NumberSelector is represented by the following classes:

    @UI("#height") 
    //@FindBy(css = "#height") 
    public static NumberSelector height;

    @Test
    public void minTest() {
        assertEquals(height.min(), 0.3);
    }

    @Test
    public void maxTest() {
        assertEquals(height.max(), 2.5);
    }

    @Test
    public void setNumberTest() {
        height.setNumber("1.4");
        assertEquals(height.value(), "1.4");
    }

    @Test
    public void stepTest() {
        assertEquals(height.step(), 0.2);
    }

    [FindBy(Css = "#height")]
    public INumberSelector numberSelector;

    [Test]
    public void GetNumberTest()
    {
        Jdi.Assert.AreEquals(number, numberSelector.Value());
    }

NumberSelector

<label for="height">Height (metres):</label>
<input type="number" id="height" min="0.3" max="2.5" step="0.2"
 placeholder="20 cm increments. Range [0.3,2.5]">

Here is the list of available methods in Java:

Method Description Return Type
is() Returns object for work with assertions NumberAssert
max() Returns the max value double
min() Returns the min value double
value() Returns the value String
setNumber(String) Sets the value void
setValue(String) Sets the value void
getValue() Returns the value String
step() Returns the step value double

Here is the list of available methods in C#:

Method Description Return Type
AssertThat() Returns object for work with assertions NumberAssert
Is() Returns object for work with assertions NumberAssert
Max Returns the max value double
Min Returns the min value double
Placeholder Returns the placeholder text String
SetNumber(double) Sets the value void
Step Returns the step value double
Value Returns the value double

Test examples in Java

Test examples in C#

BDD Steps example

1.1.12 ProgressBar

Progress Bar — Element for displaying an indicator showing the completion progress of a task.

ProgressBar

ProgressBar is located in the following class:

  @UI("#progress") 
  // @FindBy(id = "progress")
  public static ProgressBar progress;

  @Test
  public void getLabelTextTest() {
        assertEquals(progress.labelText(), "File progress");
  }

  @Test
  public void getValueTest() {
        assertEquals(progress.value(), 70);
  }

  @Test
  public void maxTest() {
        assertEquals(progress.max(), 100);
  }

  [FindBy(Css = "#progress")]
  public ProgressBar Progress;

  [Test]
  public void GetValueTest() 
  {
       Assert.AreEqual(Progress.Value(), "70");
  }

  [Test]
  public void MaxTest() 
  {
       Assert.AreEqual(Progress.Max(), "100");
  }

Here is an example with provided HTML code:

<label for="progress">File progress</label>
<progress id="progress" max="100" value="70"></progress>

Available methods in Java JDI Light:

Method Description Return Type
getValue() Get current progress value String
is() Various assert actions for Progress bar ProgressAssert
max() Get progressbar maximum possible value int
value() Get current progress value int

Test examples in Java
BDD Steps example

Available methods in C# JDI Light:

Method Description Return Type
AssertThat() Various assert actions for Progress bar ProgressAssert
Is() Various assert actions for Progress bar ProgressAssert
Max() Get progressbar maximum possible value string
Value() Get current progress value string

Test examples in C#
BDD Steps example

1.1.13 Range

  @UI("#volume")  //@FindBy(id = "volume") 
  public static Range volume;

  double defaultVolume = 90;

  @Test
  public void setupValueTest() {
        volume.setupValue(10);
        assertEquals(volume.value(), 10.0);

        defaultRange.setupValue(65);
        assertEquals(defaultRange.value(), 65.0);

        minMaxRange.setupValue(3);
        assertEquals(minMaxRange.value(), 3.0);

        fractionalRange.setupValue(3.5);
        assertEquals(fractionalRange.value(), 3.5);
  }

  @Test
 public void stepTest() {
        assertEquals(volume.step(), 5.0);
        assertEquals(defaultRange.step(), 1.0);
        assertEquals(minMaxRange.step(), 2.0);
        assertEquals(fractionalRange.step(), 0.5);
 }

  @Test
  public void maxTest() {
        assertEquals(volume.max(), 100.0);
        assertEquals(defaultRange.max(), 100.0);
        assertEquals(minMaxRange.max(), 10.0);
        assertEquals(fractionalRange.max(), 7.0);
  }
  [FindBy(Css = "#volume")]
  public IRange Volume { get; set; } 
  [Test]
  public void GetValueTest()
  {
      Assert.AreEqual(TestSite.Html5Page.DisabledRange.Value(), 50);
  }
  [Test]
  public void MinTest()
  {
      Assert.AreEqual(TestSite.Html5Page.Volume.Min(), 10);
  }
  [Test]
  public void MaxTest()
  {
      Assert.AreEqual(TestSite.Html5Page.Volume.Max(), 100);
  }
  [Test]
  public void StepTest()
  {
      Assert.AreEqual(TestSite.Html5Page.Volume.Step(), 5);
  }
  [Test]
  public void SetRangeTest()
  {
      TestSite.Html5Page.Volume.SetValue(10);
      Assert.AreEqual(TestSite.Html5Page.Volume.Value(), 10);
  }
  [Test]
  public void RangeTest()
  {
      TestSite.Html5Page.Volume.SetValue("30");
      Assert.AreEqual(TestSite.Html5Page.Volume.GetValue(), "30");
  }

Range — A graphical control element that allows the user to set the value within a range.

Range

<label for="volume">Volume</label>
<input type="text" disabled="" id="volume-value" class="range-value" value="90">
<br>
<span>10</span>
<input type="range" id="volume" min="10" max="100" value="90" step="5" class="range" list="volume-list" oninput="show_val(this)" onchange="show_val(this)">
<span>100</span>
<datalist id="volume-list">
  <option value="0">
  </option>
  <option value="20">
  </option>
  <option value="40">
  </option>
  <option value="60">
  </option>
  <option value="80">
  </option>
  <option value="100">
  </option>
</datalist>

Range is represented by the following class:

Here is a list of available methods in C#:

Method Description Return Type
AssertThat() Returns object for work with assertions RangeAssert
GetValue() Returns the value String
Is() Returns object for work with assertions RangeAssert
Max() Returns the max value Double
Min() Returns the min value Double
SetValue(string value) Sets the value void
SetValue(double value) Sets the value void
Step() Returns the step value Double
Value() Returns the value Double

Test examples in C#
BDD Steps example

And here are methods available in Java:

Method Description Return Type
getValue() Gets the value String
is() Returns object for work with assertions RangeAssert
max() Returns the max value double
min() Returns the min value double
setupValue(double volume) Sets the value void
setValue(String volume) Sets the value void
step() Returns the step value double
value() Returns the value double

Test examples in Java
BDD Steps example

1.1.14 Text

Text — Is a combination of letters and text symbols. Most testing activities involve working with text: text is typed into login fields, buttons get located by their texts, actual text gets compared to expected.

  @UI("[ui=jdi-text]") 
  //@FindBy(css = "[ui=jdi-text]") 
  public static Text jdiText;

  String text = "Powerful Framework for UI Tests Automation. Suitable for any UI project: Web(Html5, Angular, React...), Mobile(Android IOs), Desktop(Win app) etc.";

  @Test
  public void getTextTest() {
      assertEquals(jdiText.getText(), text);
  }

  @Test
  public void getValueTest() {
      assertEquals(jdiText.getValue(), text);
  }

  @Test
  public void isValidationTest() {
      jdiText.is().enabled();
      jdiText.is().text(is(text));
      jdiText.is().text(containsString("Powerful Framework for UI"));
  }

  [FindBy(Css = ".main-txt")]
  public TextElement Text;

  [Test]
  public void GetTextTest()
  {
      Jdi.Assert.AreEquals(TestSite.HomePage.Text.Value, _expectedText);
  }

  [Test]
  public void GetValueTest()
  {
      Jdi.Assert.AreEquals(TestSite.HomePage.Text.Value, _expectedText);
  }

  [Test]
  public void SetAttributeTest()
  {
      var attributeName = "testAttr";
      var value = "testValue";
      TestSite.HomePage.Text.SetAttribute(attributeName, value);
      Jdi.Assert.AreEquals(TestSite.HomePage.Text.GetAttribute(attributeName), value);
  }

  [Test]
  public void WaitSuspendButtonTextTest()
  {
       TestSite.Html5Page.Open();
       TestSite.Html5Page.GhostButton.Is.Displayed();
       TestSite.Html5Page.GhostButton.Is.Text(EqualTo("GHOST BUTTON"));
       Thread.Sleep(3000);
       TestSite.Html5Page.SuspendButton.Is.Displayed();
       TestSite.Html5Page.SuspendButton.Is.Text(EqualTo("SUSPEND BUTTON"));
  }

   [Test]
   public void IsValidationTest()
   {
        TestSite.HomePage.Text.Is.Enabled();
        TestSite.HomePage.Text.Is.Text(EqualTo(_expectedText));
        TestSite.HomePage.Text.Is.Text(ContainsString(_contains));
   }

   [Test]
   public void AssertValidationTest()
   {
        TestSite.HomePage.Text.AssertThat.Text(EqualTo(_expectedText));
   }

   [Test]
   public void BaseValidationTest()
   {
       TestSite.Html5Page.Open();
       BaseElementValidation(TestSite.Html5Page.JdiText);
   }

Text

<p ui="jdi-text">Powerful Framework for UI Tests Automation. Suitable for any UI project: 
Web(Html5, Angular, React...), Mobile(Android IOs), Desktop(Win app) etc.</p>

Text is represented by the following class:

Here is a list of available methods in C#:

Method Description Return Type
AssertThat Gets text assert TextAssert
Is Gets text assert TextAssert
GetText() returns text String
GetValue() returns text String
WaitFor Gets text assert TextAssert

Test examples in C#

And here are methods available in Java:

Method Description Return Type
getValue() Get current value String
is() Various assert actions for Text TextAssert

Test examples in Java

BDD Steps example

1.1.15 TextField

  @UI("#your-name") //@FindBy(css = "#your-name")
  public static TextField yourName;

  String defaultText = "TextField";


  @Test
  public void inputTest() {
        yourName.input("New text");
        assertEquals(yourName.getText(), "New text");
  }

  @Test
  public void sendKeysTest() {
        yourName.sendKeys("Test");
        assertEquals(yourName.getValue(), defaultText +"Test");
  }

  @Test
  public void clearTest() {
        yourName.clear();
        assertEquals(yourName.getText(), "");
  }
  [FindBy(Id = "name")]
  public ITextField NameField;

  [Test]
  public void InputTest()
  {
      TestSite.ContactFormPage.NameField.Input(ToAddText);
      Jdi.Assert.AreEquals(TestSite.ContactFormPage.NameField.Value, ToAddText);
  }

  [Test]
  public void SendKeyTest()
  {
      TestSite.ContactFormPage.NameField.SendKeys(ToAddText);
      Jdi.Assert.AreEquals(TestSite.ContactFormPage.NameField.Value, _defaultText + ToAddText);
  }

  [Test]
  public void ClearTest()
  {
      TestSite.ContactFormPage.NameField.Clear();
      Jdi.Assert.AreEquals(TestSite.ContactFormPage.NameField.Value, "");
  }

TextField — Is a simple element type that allows users to fill in text fields.

InputTypeTextField

<label for="name">Your name:</label>
<input type="text" id="name" placeholder="Input name">
<label for="disabled-name">Surname:</label>
<input type="text" id="disabled-name" placeholder="Iovlev" disabled="">

Text fields are represented by the following classes in Java and C#:

Here is a list of available methods and properties in C#:

Method / Property Description Return Type
AssertThat property that returns object for work with assertions TextAssert
Clear() clears the text field void
Focus() places cursor within the text field void
GetText() returns text from the text field String
GetValue() returns text from the text field String
Input(string text) sets new text void
Is property that returns object for work with assertions TextAssert
Placeholder returns value of the placeholder attribute String
SendKeys(string value) adds text to the field void
SetText(String value) sets new text void

Test examples in C#
BDD Steps example

And here are methods available in Java:

Method Description Return Type
getText() returns text from the text field String
getValue() returns text from the text field String
setValue(String) sets new value void
is() returns object for work with assertions TextAssert

Test examples in Java
BDD Steps example

1.1.16 TextArea

TextArea — Is a simple element type that allows users to fill in text areas (unlike TextField, multiple lines of text are allowed).

InputTypeTextArea

  @UI("#text-area") 
  // same as FindBy(css = "#text-area")
  public static TextArea textArea;

  String defaultText = "TextArea";

  @Test
  public void addNewLineTest() {
      textArea.setLines("line1", "line2");
      textArea.addNewLine("line3");
      assertEquals(textArea.getText(), "line1\nline2\nline3");
  }

  @Test
  public void isValidationTest() {
      textArea.is().enabled();
      textArea.setText(defaultText);
      textArea.is().text(is(defaultText));
      textArea.is().text(containsString("Area"));
      disabledTextArea.is().disabled();
   }

  @Test
  public void rowsTest() {
      assertEquals(textArea.rows(), 3);
      assertEquals(textArea.cols(), 33);
      assertEquals(textArea.minlength(), 10);
      assertEquals(textArea.maxlength(), 200);

      textArea.is().rowsCount(is(3));
      textArea.is().colsCount(is(33));
      textArea.is().minlength(is(10));
      textArea.is().maxlength(is(200));
  }
  [FindBy(Css = "#text-area")]
  public ITextArea TextArea;

  [Test]
  public void GetTextTest()
  {
      TextArea.SetText(Text);
      Assert.AreEqual(TextArea.GetText(), "Text");
  }

  [Test]
  public void AddNewLineTest()
  {
     TextArea.SetText("line1", "line2");
     TextArea.AddNewLine("line3");
     Assert.CollectionEquals(TextArea.GetLines(), new[] { "line1", "line2", "line3" });
  }
<label for="text-area">Text example:</label>
<textarea id="text-area" rows="3" cols="33" maxlength="200" minlength="10" required="" wrap="hard" placeholder="Input huge text">Textarea with sizing and wrap attribute (try values of hard, soft, and off to see how it affects wrapping). The maximum number of characters is constrained to 200 by the maxlength attribute.
                            </textarea>
<br>
<textarea disabled="" placeholder="Disabled area"/>

Text areas are represented by the following classes:

In Java TextArea is a descendant of UIBaseElement with HasLabel, SetValue, HasPlaceholder, IsInput interfaces parameterized with TextAreaAssert and inherits its methods. But TextArea also has methods of its own.

In C# TextArea is a descendant of TextField and inherits its methods. But TextArea also has methods of its own.

Here is a list of available methods in Java:

Method Description Return Type
addNewLine(String) add line to the already existing void
cols() returns value of cols attribute int
getLines() returns lines (text) from the text area List
getValue() calls getText() method String
getText() returns value of attribute "value" String
is() returns object for work with assertions TextAreaAssert
maxlength() returns value of maxlength attribute int
minlength() returns value of minlength attribute int
rows() returns value of rows attribute int
setLines(String...) sets lines (text) void
setValue(String) setting value void

Test examples in Java

Here is a list of available methods in C#:

Method Description Return Type
AddNewLine(string line) add line to the already existing ones void
AssertThat() returns object for work with assertions TextAreaAssert
Cols() returns value of cols attribute int
GetLines() returns lines (text) from the text area string[]
Is() returns object for work with assertions TextAreaAssert
Maxlength() returns value of maxlength attribute int
Minlength() returns value of minlength attribute int
Rows() returns value of rows attribute int
SetLines(string[] lines) sets lines (text) void

Test examples in C#

1.1.17 Title

Title — A graphical control element representing document title, which is displayed in the title bar of the browser or tab page.

Title is represented by the following class:

Title

    @UI("[ui=jdi-title]") 
    //@FindBy(css = "[ui=jdi-title]") 
    public static Label jdiTitle;

    @Test
    public void getTextTest() {
        assertEquals(jdiTitle.getText(), text);
    }

    @Test
    public void getValueTest() {
        assertEquals(jdiTitle.getValue(), text);
    }

    @Test
    public void clickTest() {
        jdiTitle.click();
        assertEquals(getAlertText(), "JDI Title");
        acceptAlert();
    }

    @Test
    public void isValidationTest() {
        jdiTitle.is().enabled();
        jdiTitle.is().text(is(text));
        jdiTitle.is().text(equalTo(text));
        jdiTitle.is().text(equalToIgnoringCase("jdi TESTING platform"));
    }    
    [FindBy(Css = "[ui=jdi-title]")]
    public Title JdiTitle;

    [Test]
    public void GetTextTest() 
    {
            Assert.AreEqual(JdiTitle.GetText(), "Title text");
    }

    [Test]
    public void ClickTest() 
    {
            JdiTitle.ClickTitle();
    }

    [Test]
    public void IsValidationTest()
    {
           TestSite.Html5Page.JdiTitle.Is.Enabled();
           TestSite.Html5Page.JdiTitle.Is.Text(EqualTo(_text));
           TestSite.Html5Page.JdiTitle.Is.Text(Is(_text));
           TestSite.Html5Page.JdiTitle.Is.Text(EqualToIgnoringCaseMatcher.EqualTo("jdi TESTING platform"));
    }

    [Test]
    public void AssertValidationTest()
    {
           TestSite.Html5Page.JdiTitle.AssertThat.Text(EqualTo(_text));
    }

    [Test]
    public void BaseValidationTest()
    {
           BaseElementValidation(TestSite.Html5Page.JdiTitle);
    }   

<h1 ui="jdi-title" onclick="alert('JDI Title');">JDI Testing platform</h1>

Here is the list of methods available in C# JDI Light:

Method Description Return Type
getValue() Returns String
Is Gets Title's assert TextAssert

Here is the list of available methods in Java JDI Light:

Method Description Return Type
AssertThat() Gets Title's assert TitleAssert
click() Click title void
getText() Returns title text String
Is() Gets Title's assert TitleAssert

Test examples in Java

Test examples in C#

1.2 HTML5 Complex elements

1.2.1 RadioButtons

RadioButtons — Interface element that allows user to select a single option from a predefined group.

Radio buttons are represented by the following class:

Consider an example where each radio button has a particular color, described by the following HTML code:

RadioButton

    //@FindBy(name = "colors")
    @UI("[name=colors]") 
    public static RadioButtons colors;

    @Test
    public void selectTest() {
        colors.select("Green");
        assertEquals(colors.getValue(), "Green");
        colorsNoLocator.select("Blue");
        colorsNoLocator.is().selected("Blue");
    }

    @Test
    public void valuesTest() {
        assertEquals(colors.values(), asList("Red", "Green", "Blue", "Yellow"));
    }

    @Test
    public void isValidationTest() {
        colors.is().selected("Blue");
        colors.is().selected(Blue);
        colors.is().values(hasItem("Yellow"));
        colors.is().disabled(hasItem("Yellow"));
        colors.is().enabled(not(hasItem("Yellow")));
        colors.is().enabled(hasItems("Green", "Blue"));

        colorsNoLocator.is().selected("Blue");
        colorsNoLocator.is().selected(Blue);
    }

    @Test
    public void assertValidationTest() {
        colors.assertThat().values(contains("Red", "Green", "Blue", "Yellow"));
    }
    [FindBy(Css = "#colors")] 
    public IRadioButtons MyRadioButtons;

    [Test]
    public void SelectRadioButton() 
    {
        MyRadioButtons.Select("some value");
    }
    [Test]
    public void SelectRadioButtonByIndex() 
    {
        MyRadioButtons.Select(1);
    }
    [Test]
    public void GetSelected() 
    {
        var selected = MyRadioButtons.GetSelected();
        Assert.AreEqual(selected, "some value");
        MyRadioButtons.Is().Selected(Is.EqualTo("some value")); 
        MyRadioButtons.AssertThat().Selected(Is.EqualTo("some value"));
    }
<input type="radio" id="red" name="colors">
<label for="red">Red</label> <br>

<input type="radio" id="green" name="colors" checked="">
<label for="green">Green</label> <br>

<input type="radio" id="blue" name="colors">
<label for="blue">Blue</label> <br>

<input type="radio" id="yellow" name="colors" disabled="">
<label for="yellow">Yellow</label>

Here is the list of some available methods in Java:

Method Description Return Type
assertThat() Returns object for work with assertions RadioButtonAssert
is() Returns object for work with assertions RadioButtonAssert
select(String/int/Enum) Select radiobutton by value/index void
selected() Get selected radiobutton value string
values() Returns list of values List

Here is the list of some available methods in C#:

Method Description Return Type
AssertThat() Returns object for work with assertions RadioButtonAssert
Is() Returns object for work with assertions RadioButtonAssert
Select(string/int) Select radiobutton by value/index void
Selected() Get selected radiobutton value string
Values() Returns list of values List

Test examples in Java

Test examples in C#

BDD Steps example

1.2.2 Table

Table — A complex element that consists of a header, a body (at least one row and one column) and a footer. This element allows several read-only interactions.

Tables are represented by the following classes in Java and C#:

Table


  @UI("#users-table") 
  //@FindBy(id = "users-table")
  @JTable(
          root = "#users-table",
          row = "//tr[%s]/td",
          column = "//tr/td[%s]",
          cell = "//tr[{1}]/td[{0}]",
          allCells = "td",
          headers = "th",
          header = {"Name", "Phone", "Email", "City"},
          rowHeader = "Name",
          size = 4
    ) 
    public static Table usersSetup;

  @Test
  public void tableDataTest() {
        assertEquals(users.row(ELEMENT.startIndex + 1).asData(UserInfo.class),
          GRADY_BROCK);
  }

  @Test
  public void tableEntityTest() {
      UserRow user = users.row(ELEMENT.startIndex + 1).asLine(UserRow.class);
      user.name.click();
      Alerts.validateAndAcceptAlert(containsString("Brock"));
      user.city.click();
      Alerts.validateAndAcceptAlert(is("Alcobendas"));
  }

  [Test]
  public void HugeTableSearchByColumnNamesContainValuesTest()
  {
      PerformancePage.UsersTable.AssertThat().HasRowWithValues(
          ContainsValue("Meyer", InColumn("Name")),
          ContainsValue("co.uk", InColumn("Email")));
      var row = PerformancePage.UsersTable.Row(
          ContainsValue("Meyer", InColumn("Name")),
          ContainsValue("co.uk", InColumn("Email")));
          Assert.AreEqual(
       "Brian Meyer;(016977) 0358;
          mollis.nec@seddictumeleifend.co.uk;Houston",
        row.GetValue());
  }

  [Test]
  public void HugeTableSearchByColumnNumbersContainValuesTest()
  {
      PerformancePage.UsersTable.AssertThat().HasRowWithValues(
          ContainsValue("Burke", InColumn(1)),
          ContainsValue("ut.edu", InColumn(3)));
      var row = PerformancePage.UsersTable.Row(1);
      PerformancePage.UsersTable.Is().HasRowWithValues( 
         HasValue("Brian Meyer", InColumn("Name")), 
         HasValue("(016977) 0358", InColumn("Phone")),
         HasValue("mollis.nec@seddictumeleifend.co.uk", 
              InColumn("Email")), 
         HasValue("Houston", InColumn("City")));
  }

  [Test]
  public void HugeTableSearchByColumnNamesHasValuesTest()
  {
      PerformancePage.UsersTable.AssertThat().HasRowWithValues(
          HasValue("Brian Meyer", InColumn("Name")),
          HasValue("mollis.nec@seddictumeleifend.co.uk",
          InColumn("Email")));
      var row = PerformancePage.UsersTable.Row(
          HasValue("Brian Meyer", InColumn("Name")),
          HasValue("mollis.nec@seddictumeleifend.co.uk",
           InColumn("Email")));
      Assert.AreEqual("Brian Meyer;(016977)
               0358;mollis.nec@seddictumeleifend.co.uk;Houston",
               row.GetValue());
  }

  [Test]
  public void HugeTableSearchByColumnNumbersHasValuesTest()
  {
      PerformancePage.UsersTable.AssertThat().HasRowWithValues(
          HasValue("Brian Meyer", InColumn(1)),
          HasValue("mollis.nec@seddictumeleifend.co.uk",
           InColumn(3)));
      var row = PerformancePage.UsersTable.Row(
          ContainsValue("Meyer", InColumn("Name")),
          ContainsValue("co.uk", InColumn("Email")));
      Assert.AreEqual("Brian Meyer;
          (016977) 0358;mollis.nec@seddictumeleifend.co.uk;Houston",
          row.GetValue());
  } 

  [Test]
  public void TableChainTest()
  {            
      PerformancePage.UsersTable.AssertThat()
          .Size(400)
          .Size(Is.GreaterThan(399))                
          .HasRowWithValues(
              HasValue("Brian Meyer", InColumn("Name")),
              HasValue("mollis.nec@seddictumeleifend.co.uk", 
             InColumn("Email")))
          .NotEmpty()
          .RowsWithValues(3, ContainsValue("Baker", InColumn(1)))
          .HasColumn("Email")
          .HasColumns(new[] {"Name", "City"})
          .Columns(Is.SubsequenceOf(new[] {"Name", "City", "Phone",
           "Email", "Address"}));
  }

  [Test]
  public void TableRowPerformanceTest()
  {
      PerformancePage.Open();
      PerformancePage.CheckOpened();
      AreEqual("Burke Tucker;076 1971 1687;et.euismod.et@ut.edu;GozŽe",
         PerformancePage.UsersTable.Row(1).GetValue());
      AreEqual("Burke Tucker;076 1971 1687;et.euismod.et@ut.edu;GozŽe",
        PerformancePage.UsersTable.Row("Burke Tucker").GetValue());
      AreEqual("Burke Tucker;076 1971 1687;et.euismod.et@ut.edu;GozŽe", 
        PerformancePage.UsersTable.Row(Users.Name).GetValue());
      var value = PerformancePage.UsersTable.Preview();
      AreEqual("Name Phone Email City" +
        "Burke Tucker 076 1971 1687 et.euismod.et@ut.edu GozŽe"+
        "Grady Brock (011307) 16843 cursus.et@commodo.org Alcobendas"+
        "Harding Lloyd 0800 1111 neque.In.ornare@mauris.co.uk Beauvais",
                           value.Substring(0, 194));
  }

  [Test]
  public void TableCellPerformanceTest()
  {
      PerformancePage.Open();
      PerformancePage.CheckOpened();
      AreEqual("ipsum.non.arcu@auctorullamcorper.ca",
         PerformancePage.UsersTable.Cell(3, 4));
      AreEqual("ipsum.non.arcu@auctorullamcorper.ca",
         PerformancePage.UsersTable.Cell("Email", 4));
      AreEqual("ipsum.non.arcu@auctorullamcorper.ca",
         PerformancePage.UsersTable.Cell(3, "Zachary Hendrix"));
      AreEqual("ipsum.non.arcu@auctorullamcorper.ca",
         PerformancePage.UsersTable.Cell("Email", "Zachary Hendrix"));
  }

  [Test]
  public void TableColumnPerformanceTest()
  {
      PerformancePage.Open();
      PerformancePage.CheckOpened();
      AreEqual("076 1971 1687;(011307) 16843;0",
         PerformancePage.UsersTable.Column(2).
           GetValue().Substring(0, 30));
      AreEqual("076 1971 1687;(011307) 16843;0",
      PerformancePage.UsersTable.Column("Phone").
          GetValue().Substring(0, 30));
      AreEqual("076 1971 1687;(011307) 16843;0",
      PerformancePage.UsersTable.Column(Users.Phone).
          GetValue().Substring(0, 30));
  }     
<table class="uui-table stripe tbl-without-header table-td-click"
                ui="table" id="users-table">
    <tbody>
        <tr>
            <th>Name</th>
            <th>Phone</th>
            <th>Email</th>
            <th>City</th>
        </tr>
        <tr>
            <td>Burke Tucker</td>
            <td>076 1971 1687</td>
            <td>et.euismod.et@ut.edu</td>
            <td>GozŽe</td>
        </tr>
        <tr>
            <td>Grady Brock</td>
            <td>(011307) 16843</td>
            <td>cursus.et@commodo.org</td>
            <td>Alcobendas</td>
        </tr>
        <tr>
            <td>Harding Lloyd</td>
            <td>0800 1111</td>
            <td>neque.In.ornare@mauris.co.uk</td>
            <td>Beauvais</td>
        </tr>
    </tbody>
</table>

JDI JTable annotation

Along with providing a Table type element JDI Light also provides a @JDropdown annotation for a better element locating. In addition to what Table type does @JDropdown also allows some kind of customization in the way the element is being located on the page.

This annotation has the following fields that can be used for locating a table element:

Here is a list of available methods in Java:

Method Description Return Type
getStartIndex() Returns start index int
setStartIndex(int) Sets start index void
core() Returns a UIElement UIElement
setHeader(List) Sets header value void
headerUI() Returns a header name WebList
footerUI() Returns a footer name WebList
rowHeader() Returns a value of a table header corresponding to a particular raw List
cell(int, int) Returns a cell object of a table according to column number and row number String
cell(int, String) Returns a cell object of a table according to the row number and column name String
cell(String, int) Returns a cell object of a table according to the column name and row number String
cell(String, String) Returns a cell object of a table according column name and row name String
column(Enum<?>) Returns a column object of a table according to column name Line
column(int) Returns a column object of a table according to column number Line
column(String) Returns a column object of a table according to column name Line
columns() Returns a list of column objects of a table List
count() Returns amount of rows int
filterRows(Matcher, Column) Sets and returns a list of filtered rows of a table according to matching column List
filterRows(Pair,Column>...) Sets and returns a list of filtered rows of a table according to matching column List
getValue() Returns a string content of values for a particular row, where values are separated by ";" String
header() Returns a list of table's headers List
isEmpty() Asserts whether a table is empty boolean
isNotEmpty() Asserts whether a table is not empty boolean
preview() Returns table preview String
row(Matcher, Column) Check that the table has rows that meet expected condition Line
row(Enum<?>) Returns a row object of a table according to row name Line
row(int) Returns a row object of a table according to row number Line
row(Pair,Column>) Returns a row object of a table according to matching column Line
row(String) Returns a row object of a table according to row name Line
row(ColumnMatcher...) Returns a row object of a table according to matcher Line
rows() Returns a list of rows of a table List
rows(ColumnMatcher...) Get all table rows that match criteria List
rowsImages() Get all table rows List
setup(Field) Initialize field void
getTableJs() Returns table T
clear() clears the text field void
refresh() Clears all data and lines void
offCache() Turns off cache usage void
size() Returns amount of columns int
validateRowIndex(int) Validates row index void
webRow(int) Returns all UIElements in the row according to row number WebList
webRow(int,String) Returns all UIElements in the row according to row number WebList
webRow(String) Returns all UIElements in the row according to row name WebList
webRow(Enum<?>) Returns all UIElements in the row according to row name List
webColumn(int) Returns all UIElements in the column according to column number WebList
webColumn(String) Returns all UIElements in the column according to column name WebList
webColumn(Enum<?>) Returns all UIElements in the column according to column name WebList
webCell(int, int) Returns all UIElements in the column according to cell position UIElement
getJSValues(String) Returns list of locators List
jsCells() Returns list of locators List
jsColumn(int) Returns list of column locators List
jsColumn(String) Returns list of column locators List
jsRow(int) Returns list of row locators List
jsRow(String) Returns list of row locators List
jsRowIndexByName(String) Returns row index by its name int
getRowIndexByName(String) Returns row index by its name int
getRow(int) Returns row by its row number WebList
getColumn(int) Returns column by its row number WebList
getCell(int,int) Returns cell by its column number and row number UIElement
filter() Filters a table WebList
filterBy(String) Filters a table with by a filterName UIElement
searchBy(String) Filter {name} by column {0} UIElement

And here are methods available in C#:

Method Description Return Type
AssertThat() Applicable for performing assert actions for tables TableAssert
Cell(int colNum, int rowNum) Sets and returns a cell object of a table according to the cell's indices string
Cell(string colName, int rowNum) Sets and returns a cell object of a table according to the cell's column name and row index string
Cell(int colNum, string rowName) Sets and returns a cell object of a table according to the cell's column index and row name string
Cell(string colName, string rowName) Sets and returns a cell object of a table according to the cell's column name and row name string
Column(int colNum) Sets and returns a column object of a table according to the column's index Line
Column(string colName) Sets and returns a column object of a table according to the column's name Line
Column(Enum colName) Sets and returns a column object of a table according to column name Line
Columns() Sets and returns a list of column objects of a table List
Columns(Matcher> condition) Asserts whether headers satisfy some matcher condition TableAssert
ContainsValue(string value, Column column) Looks for an object by some value occurrence in a particular column TableMatcher
Empty() Asserts whether table is empty TableAssert
FilterRows(Matcher matcher, Column column) Sets and returns a list of filtered rows of a table according to matching column List
FilterRows(params KeyValuePair, Column>[] matchers) Sets and returns a list of filtered rows of a table according to matching column List
GetValue() Returns a string content of values for a particular row, where values are separated by ";" string
HasColumn(string column) Asserts whether table has a particular header TableAssert
HasColumns(IEnumerable columns) Asserts whether table has particular headers TableAssert
HasRowWithValues(params TableMatcher[] matchers) Asserts whether a row with particular matchers exists in a table TableAssert
HasValue(string value, Column column) Looks for an object (exact match) in a particular column TableMatcher
Is() Applicable for performing assert actions for tables TableAssert
InColumn(string value) Sets an object of some column to a particular value Column
InColumn(int num) Sets an object of some column to a particular column number Column
NotEmpty() Asserts whether table is not empty TableAssert
Row(params TableMatcher[] matchers) Sets and returns a row object from a table according to some matcher params (returns 'null' if there is no such row) Line
Row(int rowNum) Sets and returns a row object of a table according to the row index Line
Row(string rowName) Sets and returns a row object of a table according to the row name Line
Row(Enum rowName) Sets and returns a row object of a table according to row name Line
Row(Matcher matcher, Column column) Sets and returns a row object of a table according to matching column Line
Row(params KeyValuePair, Column>[] matchers) Sets and returns a row object of a table according to matching column Line
RowsAsLines(params TableMatcher[] matchers) Sets and returns a list of rows of a table according to matchers List
RowsAsLines() Sets and returns a list of rows of a table List
RowsWithValues(int count, params TableMatcher[] matchers) Asserts whether rows with particular matchers exist in a table multiple times TableAssert
string Preview() Returns a string content of the whole table string
Size(Matcher condition) Asserts whether table size satisfies some matcher condition TableAssert
Size(int expectedSize) Asserts whether table has a particular size TableAssert

Test examples in Java

Test examples in C#

BDD Steps example

1.2.3 DataTable

DataTable — A complex element that consists of a header, a body (at least one row and one column) and a footer. You are able to perform a list of read-only interactions with this element in order to get all data based on specified criteria.

DataTables are represented by the following classes in Java:

  @UI("#users-table") 
  //@FindBy(id = "users-table")
  public static DataTable<UserRow, UserInfo> usersData;
  @JTable(
          root = "#users-table",
          row = "//tr[%s]/td",
          column = "//tr/td[%s]",
          cell = "//tr[{1}]/td[{0}]",
          allCells = "td",
          headers = "th",
          header = {"Name", "Phone", "Email", "City"},
          rowHeader = "Name",
          size = 4
    )
  public static DataTable<UserRow, UserInfo> usersDataSetup;

  public static UserInfo GRADY_BROCK = new UserInfo().set(u-> {
        u.name = "Grady Brock";
        u.email = "cursus.et@commodo.org";
        u.phone = "(011307) 16843";
        u.city = "Alcobendas";
  });

  @Test
  public void filterDataTest() {
      assertEquals(usersData.dataRow(ELEMENT.startIndex + 1), GRADY_BROCK);
      assertEquals(usersData.dataRow("Grady Brock"), GRADY_BROCK);
      assertEquals(usersData.dataRow(d -> d.name.contains("Brock")), GRADY_BROCK);
      usersData.assertThat().row(d -> d.equals(GRADY_BROCK));
      usersData.has().row(GRADY_BROCK);
  }

  @Test
  public void filterLinesTest() {
      UserRow line =  usersData.line(ELEMENT.startIndex + 1);
      validateUserRow(line);
      line =  usersData.line("Grady Brock");
      validateUserRow(line);
      line =  usersData.line(d -> d.name.contains("Brock"));
      validateUserRow(line);
  }

  private void validateUserRow(UserRow line) {
      line.city.click();
      Alerts.validateAndAcceptAlert(is(GRADY_BROCK.city));
      assertEquals(line.email.getText(), GRADY_BROCK.email);
  }

DataTable

<table class="uui-table stripe tbl-without-header table-td-click"
     ui="table" id="users-table">
    <tbody>
        <tr>
            <th>Name</th>
            <th>Phone</th>
            <th>Email</th>
            <th>City</th>
        </tr>
        <tr>
            <td>Burke Tucker</td>
            <td>076 1971 1687</td>
            <td>et.euismod.et@ut.edu</td>
            <td>GozŽe</td>
        </tr>
        <tr>
            <td>Grady Brock</td>
            <td>(011307) 16843</td>
            <td>cursus.et@commodo.org</td>
            <td>Alcobendas</td>
        </tr>
        <tr>
            <td>Harding Lloyd</td>
            <td>0800 1111</td>
            <td>neque.In.ornare@mauris.co.uk</td>
            <td>Beauvais</td>
        </tr>
    </tbody>
</table>

Here is a list of available methods in Java (DataTable expand Table class - methods from previous table are available too_):

In return types, column "D" refers to the user data object and "L" refers to the table line object.

Method Description Return Type
dataRow(int) Get table row by the row number D
allData() Get all table rows List
allData(MapArray>) Get all table rows List
allLines() Gets all object rows from the specified table List
allLines(MapArray>) Gets all object rows from the specified table List
columnValues(String, Class) Returns column values List
dataRow(String) Get table row by the row name D
dataRow(Enum<?>) Get table row by the row name D
dataRow(Matcher,Column) Get table row that match criteria in column D
dataRow(ColumnMatcher...) Get first table row that match criteria D
dataRow(JFunc1) Get first table row that match criteria D
dataRow(Pair, Column>...) Get table row that match criteria in column D
dataRows(JFunc1) Get all table rows that match criteria List
dataRows(ColumnMatcher...) Get all table rows that match criteria List
dataRows(JFunc1,int) Get at least a specified number of rows of the table that meet the criteria List
filterData(Matcher,Column) Get table rows that match criteria in column List
filterDatas(Pair,Column>...) Get table rows that match criteria in column List
filterLines(Matcher,Column) Get table rows that match criteria in column List
filterLines(Pair,Column>...) Get table rows that match criteria in column List
get(String) Returns values of the specified row D
getValue() Get table value String
elements(int) Returns elements of table List
line(Enum<?>) Returns an object of a table according to row name L
line(int) Returns an object of a table according to row number L
line(JFunc1) Get first table row that match criteria L
line(Matcher, Column) Get table row that match criteria in column L
line(Pair,Column>...) Get table row that match criteria in column L
line(ColumnMatcher...) Get first table row that match criteria L
line(String) Get table row by the row name L
lines(JFunc1) et first table row that match criteria List
lines(ColumnMatcher...) Get all table rows that match criteria List
offCache() Turns off cache usage void
refresh() Clears all data and lines void
setup(Field) Sets up the table using specified fields void
is() Returns object for work with assertions DataTableAssert
is(Matcher<? super List>) Returns object for work with assertions DataTableAssert
assertThat(Matcher<? super List>) Returns object for work with assertions DataTableAssert
verify(Matcher<? super List>) Returns object for work with assertions DataTableAssert

Test examples in Java

BDD Steps example

1.2.4 Dropdown

Dropdown — A graphical control element that allows user to choose a single value from a list.

DropDown

JDI Light has support for dropdown elements with their own type. There are several ways of dropdown usage in JDI Light, each serving different needs.

Dropdown representation

JDI Light provides a Dropdown class which is using for dropdown representation as a type of web element.

This class can also be used when working with HTML5 elements in cases when dropdown is represented with HTML <select> tag.

Consider an example of HTML5 dropdown with the given HTML code:

Dropdown HTML5

    @JDropdown(root = "div[ui=dropdown]",
        value = ".filter-option",
        list = "li",
        expand = ".caret")
    public static Dropdown colors2; //@FindBy(css = "div[ui=dropdown]")

    @Test
    public void selectStringTest() {
         colors2.select("Red");
         lastLogEntry.assertThat()
             .text(containsString("Colors: value changed to Red"));
    }

    @Test
    public void selectEnumTest() {
        colors2.select(Green);
        lastLogEntry.assertThat()
            .text(containsString("Colors: value changed to Green"));
    }

    @Test
    public void selectIndexTest() {
        colors2.select(ELEMENT.startIndex + 3);
        lastLogEntry.assertThat()
            .text(containsString("Colors: value changed to Blue"));
    }    
    [FindBy(Css = "#dress-code")] 
    public Dropdown DressCode;

    [Test]
    public void SelectEnumTest() 
    {
        DressCode.Select(Fancy);
        Assert.AreEquals(DressCode.GetSelected(), "Fancy");
    }

    [Test]
    public void LabelTest()
    {
        AreEqual(TestSite.Html5Page.DressCode.Label().GetText(), "Dress code:");
        TestSite.Html5Page.DressCode.Label().Is.Text(ContainsString("Dress"));
    }

    [Test]
    public void IsValidationTest()
    {
        TestSite.Html5Page.DressCode.Is.Selected("Casual");
        TestSite.Html5Page.DressCode.Is.Selected(DressCode.Casual);
        TestSite.Html5Page.DressCode.Is.Values(HasItems(new[] { "Pirate" }));
        TestSite.Html5Page.DressCode.Is.Disabled(HasItems(new[] { "Disabled" }));
        TestSite.Html5Page.DressCode.Is.Enabled(HasItems(new[] { "Pirate", "Fancy" }));
    }

    [Test]
    public void AssertValidationTest()
    {
        TestSite.Html5Page.DressCode.AssertThat.Values(
        ContainsInAnyOrder(new[] {"Fancy", "Casual", "Disabled", "Pirate"}));
    }

    [Test]
    public void BaseValidationTest()
    {
        BaseElementValidation(TestSite.Html5Page.DressCode);
    }

<select id="dress-code">
    <option value="fancy">Fancy</option>
    <option value="casual" selected="">Casual</option>
    <option value="disabled" disabled="">Disabled</option>
    <option value="pirate">Pirate</option>
</select>

JDI Dropdown annotation

For convenience, JDI Light provides a @JDropdown annotation to locate dropdown elements. This annotation can be used in cases when working with a complex element that may have a more complicated HTML structure. JDropdown annotation allows to customize navigation of the web element inner structure by using annotation default methods.

[JDropDown(root: "#colors", 
           value: ".filter-option", 
           list:"li", 
           expand:".caret")]
public Droplist Colors;

[Test]
public void ComplexTest() 
{
    MetalAndColorsPage.ShouldBeOpened();
    MetalAndColorsPage.Colors.Select(Green);
}
<div class="form-group colors" ui="dropdown" id="colors">
    <select class="selectpicker uui-form-element" style="display: none;">
        <option>Colors</option>
        <option>Red</option>
        <option>Green</option>
        <option>Blue</option>
        <option>Yellow</option>
    </select>
    <div class="btn-group bootstrap-select uui-form-element"><button type="button"
            class="btn dropdown-toggle selectpicker btn-default" data-toggle="dropdown" title="Colors"><span
                class="filter-option pull-left" value="">Colors</span>&nbsp;<span class="caret"></span></button>
        <div class="dropdown-menu open" style="max-height: 933px; overflow: hidden; min-height: 90px;">
            <ul class="dropdown-menu inner selectpicker" role="menu"
                style="max-height: 921px; overflow-y: auto; min-height: 78px;">
                <li rel="0" class="selected"><a tabindex="0" class="" style=""><span class="text">Colors</span>
                    <i class="glyphicon glyphicon-ok icon-ok check-mark"></i></a></li>
                <li rel="1"><a tabindex="0" class="" style=""><span class="text">Red</span>
                    <i class="glyphicon glyphicon-ok icon-ok check-mark"></i></a></li>
                <li rel="2"><a tabindex="0" class="" style=""><span class="text">Green</span>
                    <i class="glyphicon glyphicon-ok icon-ok check-mark"></i></a></li>
                <li rel="3"><a tabindex="0" class="" style=""><span class="text">Blue</span>
                    <i class="glyphicon glyphicon-ok icon-ok check-mark"></i></a></li>
                <li rel="4"><a tabindex="0" class="" style=""><span class="text">Yellow</span>
                    <i class="glyphicon glyphicon-ok icon-ok check-mark"></i></a></li>
            </ul>
        </div>
    </div>
</div>

JDropdown annotation consists of the following elements using which element inner structure can be customised:

Here is a list of some available methods:

Method Description Return Type
iCore() UIElement
list() Returns a WebList item representing a list of available Dropdown options WebList
select(String/int) Select the specified element by the value void
isDisplayed() Show\wait that dropdown element displayed on the screen boolean
selected(String) Is 'String' selected boolean
selected() Check that '{name}' is displayed String
values() Get '{name}' values List
getText() Gets element text String
getValue() Gets element value String
setValue(String) Sets element value void
setup(Field field) Setup the dropdown using specified fields void
size() Return amount of elements in the list int

Available Assert methods in C#:

Method Description Return Type
AssertThat Gets dropdown assertion DropDownAssert
Disabled(Matcher> condition) Checks that dropdown values are disabled by some condition DropDownAssert
Enabled(Matcher> condition) Checks that dropdown values are enabled by some condition DropDownAssert
Is Gets dropdown assertion DropDownAssert
Selected(string option) Checks whether some option is selected DropDownAssert
Selected(Enum option) Checks whether some option is selected DropDownAssert
Values(Matcher> condition) Checks that dropdown values match some condition DropDownAssert

Test examples in Java

Test examples in C#

BDD test examples


1.2.5 MultiDropdown

MultiDropdown – A graphical control element that allows user to choose several values from a list.

DropDown

JDI Light provides a MultiSelector class which is using for MultiDropdown representation as a type of web element.

    //@FindBy(id = "multi-dropdown")
    @UI("#multi-dropdown") 
    public static MultiSelector multiDropdown;

    @Test
    public void selectTest() {
        skipForFirefox();
        multiDropdown.check("Electro", "Metalic");
        assertEquals(multiDropdown.checked(), asList("Electro", "Metalic"));
    }

    @Test
    public void disabledTest() {
        skipForFirefox();
        multiDropdown.select("Disabled");
        assertEquals(multiDropdown.selected(), "Steam");
    }

    @Test
    public void labelTest() {
        assertEquals(multiDropdown.label().getText(), "Multi dropdown:");
        multiDropdown.label().is().text(containsString("Multi"));
    }

    @Test
    public void isValidationTest() {
        multiDropdown.is().selected("Steam");
        multiDropdown.is().selected(Steam);
        multiDropdown.assertThat().values(hasItem("Wood"));
        multiDropdown.assertThat().disabled(hasItem("Disabled"))
            .enabled(not(hasItem("Disabled")))
            .enabled(hasItems("Electro", "Metalic"));
    }
[FindBy(Css = "#multi-dropdown")]
public MultiDropdown MultiDropdown { get; set; }

[Test]
public void SelectMultipleOptions()
{
    var optionsList = new List<string> { "Steam", "Electro" };
    TestSite.Html5Page.MultiDropdown.SelectOptions(optionsList);
    Jdi.Assert.IsTrue(TestSite.Html5Page.MultiDropdown.OptionsAreSelected(optionsList));
}

[Test]
public void CheckOptionExists()
{
    TestSite.Html5Page.MultiDropdown.Expand();
    Jdi.Assert.IsTrue(TestSite.Html5Page.MultiDropdown.OptionExists("Steam"));
    Jdi.Assert.IsFalse(TestSite.Html5Page.MultiDropdown.OptionExists("Steam2"));
}

[Test]
public void CheckOptionIsDisabled()
{
    TestSite.Html5Page.MultiDropdown.Expand();
    Jdi.Assert.IsFalse(TestSite.Html5Page.MultiDropdown.OptionIsEnabled("Disabled"));
    Jdi.Assert.IsTrue(TestSite.Html5Page.MultiDropdown.OptionIsEnabled("Wood"));
}

[Test]
public void LabelTest()
{
    Jdi.Assert.AreEquals(TestSite.Html5Page.MultiDropdown.Label().GetText(), "Multi dropdown:");
    TestSite.Html5Page.MultiDropdown.Label().Is.Text(ContainsString("Multi"));
}

[Test]
public void IsValidationTest()
{
    TestSite.Html5Page.MultiDropdown.SelectOptions(new List<string> { "Steam" });
    TestSite.Html5Page.MultiDropdown.Is.Selected("Steam");
    TestSite.Html5Page.MultiDropdown.Is.Selected(Ages.Steam);
    TestSite.Html5Page.MultiDropdown.Is.Values(HasItems( new []{ "Wood" }));
    TestSite.Html5Page.MultiDropdown.Is.Disabled(HasItems(new[] { "Disabled" }));
    TestSite.Html5Page.MultiDropdown.Is.Enabled(HasItems( new []{ "Electro", "Metalic" }));
}

[Test]
public void AssertValidationTest()
{
    TestSite.Html5Page.MultiDropdown.SelectOptions(new List<string> { "Steam" });
    TestSite.Html5Page.MultiDropdown.AssertThat.Values(ContainsInAnyOrder( new []{ "Disabled", "Electro", "Metalic", "Wood", "Steam" }));
}

[Test]
public void BaseValidationTest()
{
    BaseElementValidation(TestSite.Html5Page.MultiDropdown);
}
<span class="multiselect-native-select">
   <select id="multi-dropdown" multiple="multiple">
      <option value="electro">Electro</option>
      <option value="steam" selected="">Steam</option>
      <option value="metalic">Metalic</option>
      <option value="dis" disabled="">Disabled</option>
      <option value="wood">Wood</option>
   </select>
   <div class="btn-group">
      <button type="button" class="multiselect dropdown-toggle btn btn-default" data-toggle="dropdown" title="Steam">
      <span class="multiselect-selected-text">Steam</span>
      <b class="caret"/>
      </button>
      <ul class="multiselect-container dropdown-menu">
         <li>
            <a tabindex="0">
            <label class="checkbox" title="Electro">
            <input type="checkbox" value="electro"> Electro</label>
            </a>
         </li>
         <li class="active">
            <a tabindex="0">
            <label class="checkbox" title="Steam">
            <input type="checkbox" value="steam"> Steam</label>
            </a>
         </li>
         <li>
            <a tabindex="0">
            <label class="checkbox" title="Metalic">
            <input type="checkbox" value="metalic"> Metalic</label>
            </a>
         </li>
         <li class="disabled">
            <a tabindex="-1">
            <label class="checkbox" title="Disabled">
            <input type="checkbox" value="dis" disabled=""> Disabled</label>
            </a>
         </li>
         <li>
            <a tabindex="0">
            <label class="checkbox" title="Wood">
            <input type="checkbox" value="wood"> Wood</label>
            </a>
         </li>
      </ul>
   </div>
</span>

MultiDropdown are represented by the following classes:

The list of methods available for Java in JDI Light:

Method Description Return Type
list() locator representing list options WebList
select(String/int) Selects the value based on its visible text/index WebList
check(String/String.../TEnum.../int...) Check that only particular elements are selected void
checked() Get checked elements List
is() Applicable for performing assert actions for MultiDropdown UIMSelectAssert
selected() Get selected value String
selected(String) Get selected value boolean
values() Get the elements values List
values(TextTypes) Get the elements values List
listEnabled() Get the list of enabled elements List
listDisabled() Get the list of disabled elements List
setValue() Sets element value void
getValue() Gets element value String
getStartIndex() Gets start index int
setStartIndex(int) Sets start index void
unckeckAll(String) Uncheck all selected elements void
uncheck(String.../TEnum.../int.../String) Unchecks particular elements by index/name void

Here is the list of some methods available for C# in JDI Light:

Method Description Return Type
AssertThat Gets multiDropDown assert MultiDropdownAssert
Close() Close expanded list void
Disabled(Matcher> condition) Check whether some values are disabled in MultiDropDown by some matcher MultiDropdownAssert
Enabled(Matcher> condition) Check whether some values are enabled in MultiDropDown by some matcher MultiDropdownAssert
Expand() Expand list void
GetSelectedOptions() Get selected options List
Is Gets multiDropDown assert MultiDropdownAssert
OptionIsEnabled(string) Check whether option is enabled bool
OptionExists(string) Check whether option exists in list bool
SelectOption(string) Select specified option void
SelectOptions(List) Select specified options void
Selected(string option) Check whether option is selected MultiDropdownAssert
Selected(Enum option) Check whether option is selected MultiDropdownAssert
Values(Matcher> condition) Check whether some values exist in MultiDropDown by some matcher MultiDropdownAssert

Test examples in Java

Test examples in C#

BDD Steps example

1.2.6 DataList

DataList – A graphical control element that allows user to choose one value from a list or enter it by himself. DataList element contains a set of options with values available as inputs.

DataList

DataList is provided by JDI Light in:

C# JDI DataList annotation

For better use in C# JDI Light provides a [JDataList] annotation to locate DataList elements. This annotation consists of the following elements:

    // @FindBy(id = "ice-cream-flavors")
    @UI("#ice-cream-flavors") 
    public static DataListOptions iceCream;

    @Test
    public void getValueTest() {
        assertEquals(iceCream.getValue(), "Coconut");
    }

    @Test
    public void getTextTest() {
        assertEquals(iceCream.getText(), "Coconut");
    }

    @Test
    public void inputTest() {
        iceCream.input("New text");
        assertEquals(iceCream.getText(), "New text");
    }

    @Test
    public void inputNullValueTest() {
        String value = iceCream.getText();
        iceCream.input(null);
        iceCream.has().text(value);
    }

    @Test
    public void clearTest() {
        iceCream.clear();
        assertEquals(iceCream.getText(), "");
    }

    @Test
    public void selectTest() {
        iceCream.select("Chocolate");
        assertEquals(iceCream.getValue(), "Chocolate");
    }
    [JDataList("#ice-cream", "#ice-cream-flavors > option")]
    public DataList IceCream { get; set; }

    [JDataList("#disabled-dropdown","#disabled-dropdown > option")]
    public DataList DisabledDropdownAsDataList { get; set; }

    [Test]
    public void GetValueTest()
    {
        AreEqual(TestSite.Html5Page.IceCream.Selected(), "Coconut");
    }

    [Test]
    public void LabelTest()
    {
        AreEqual(TestSite.Html5Page.IceCream.Label().GetText(), "Choose your lovely icecream");
        TestSite.Html5Page.IceCream.Label().Is.Text(ContainsString("lovely icecream"));
    }

    [Test]
    public void IsValidationTest()
    {
         TestSite.Html5Page.IceCream.Is.Enabled();
         TestSite.Html5Page.IceCream.Is.Attr("value" ,EqualTo(_text));
         TestSite.Html5Page.IceCream.Select("Vanilla");
         TestSite.Html5Page.IceCream.Is.Attr("value", ContainsString("Van"));
    }

    [Test]
    public void AssertValidationTest()
    {
         TestSite.Html5Page.IceCream.AssertThat.Attr("value", ContainsString(_text));
    }

    [Test]
    public void BaseValidationTest()
    {
         BaseElementValidation(TestSite.Html5Page.IceCream);
    }

    [Test]
    public void NegativeSelectTest()
    {
         Throws<ElementNotSelectableException>(() => TestSite.Html5Page.DisabledDropdownAsDataList.Select("Fancy", false));
    }

    [Test]
    public void NegativeSelectEnumTest()
    {
          Throws<ElementNotSelectableException>(() => TestSite.Html5Page.DisabledDropdownAsDataList.Select(DressCode.Fancy, false));
    }

    [Test]
    public void NegativeSelectNumTest()
    {
          Throws<ElementNotFoundException>(() => TestSite.Html5Page.IceCream.Select(7, false));
    }

    [Test]
    public void AssertOptionsValuesTest()
    {
          IsTrue(TestSite.Html5Page.IceCream.Values().SequenceEqual(_options));
    }

Have a look at the following example with HTML code provided:

<datalist id="ice-cream-flavors">
    <option value="Chocolate"></option>
    <option value="Coconut"></option>
    <option value="Mint"></option>
    <option value="Strawberry"></option>
    <option value="Vanilla"></option>
</datalist>

The list of methods available for Java in JDI Light:

Method Description Return Type
list() Returns a WebList item representing a list of available Datalist options WebList
getText() Gets button text String
listEnabled() Return list of values of enabled options List
listDisabled() Return list of values of disabled options List
isEnabled() Check that '{name}' is enabled boolean
isDisplayed() Check that '{name}' is displayed boolean
isExpanded() Return if element expanded boolean
isCollapsed() Checks whether element is collapsed boolean
is() Returns DropdownAssert class DropdownAssert
getStartIndex() Returns start index int
setStartIndex() Sets start index void
select(String/int) Select combobox option by value or index void
selected() Get selected option value String
values() Get all option values from combobox List

Here is the list of some methods available for C# in JDI Light:

Method Description Return Type
assertThat() Returns object for work with assertions ComboBoxAssert
Expand() Expands the list of possible values void
GetSelected() Get selected combobox value string
Input(string) Input user's value into combobox void
is() Returns object for work with assertions ComboBoxAssert
Select(string/int) Select combobox by value/index void

Test examples in Java

Test examples in C#

BDD Steps example

1.2.7 CheckList

CheckList – A graphical control element representing a set of checkboxes, each of which allows user to control a two-state parameter (enabled or disabled).

Checklist element type is available in the following packages:

See an example with HTML code describing checklist element.

Checklist Example


  //@FindBy(name = "checks-group")
  @UI("[name=checks-group]")
  public static Checklist weather;

  @Test
  public void getValueTest() {
      assertEquals(weather.getValue(), "Hot option");
  }

  @Test
  public void checkTest() {
      weather.check("Cold");
      assertEquals(weather.checked(), asList("Cold"));
  }

  @Test
  public void uncheckTest() {
      weather.check("Rainy day", "Sunny");
      weather.uncheck("Rainy day");
      weather.is().checked(hasSize(3));
      weather.is().checked(hasItems("Hot option", "Cold", "Sunny"));
  }

  @Test
  public void selectTest() {
      weather.select("Cold");
      assertEquals(weather.checked(), asList("Hot option", "Cold"));
  }
  [FindBy(Css = "div:nth-child(11) > div.html-left")]
  public ICheckList weather;

  [FindBy(Css = "div:nth-child(11) > div.html-left")]
  public ICheckList<MyCheckBox> genericWeather;

  [Test]
  public void CheckCheckList()
  {
      weather.Check("Cold", "Hot option");
      Jdi.Assert.CollectionEquals(new[] { "Cold", "Hot option" }, weather.Checked());
  }

  [Test]
  public void UncheckTest()
  {
      _weather.Check(false, "Rainy day", "Sunny");
      _weather.Uncheck(false, "Rainy day", "Sunny");
      _weather.Is.Selected(HasSize(2));
      _weather.Is.Selected(HasItems(new[] { "Hot option", "Cold" }));
  }

  [Test]
  public void IsValidationTests()
  {
      weather.AssertThat
                  .Values(HasItems(new[] {"Cold", "Sunny"}))
                  .Disabled(HasItems(new[] {"Disabled"}))                
                  .Size(Is.LessThan(6))
                  .AllDisplayed();
  }

  [Test]
  public void UncheckAllTest()
  {
      _weather.Uncheck(false, "Rainy day", "Sunny");
      _weather.UncheckAll();
      _weather.Is.Selected(HasSize(0));
  }

  [Test]
  public void CheckAllTest()
  {
      _weather.CheckAll();
      _weather.Is.Selected(HasSize(4));
      _weather.Is.Selected(HasItems(new[] { "Hot option", "Cold", "Rainy day", "Sunny" }));
  }

  [Test]
  public void IsDisabledTest()
  {
      _weather.Select(false, "Disabled");
      _weather.Is.Selected(HasItems(new [] { "Hot option" } ));
  }
<input type="checkbox" id="hot" name="checks-group" checked="">
<label for="hot">Hot option</label> <br>

<input type="checkbox" id="cold" name="checks-group">
<label for="cold">Cold</label> <br>

<input type="checkbox" id="rainy" name="checks-group">
<label for="rainy">Rainy day</label> <br>

<input type="checkbox" id="sunny-day" name="checks-group">
<label for="sunny-day">Sunny</label> <br>

<input type="checkbox" id="disabled-ch" name="checks-group" disabled="">
<label for="disabled-ch">Disabled</label>

List of available methods in Java JDI Light:

Method Description Return Type
list() Returns a WebList item representing a list of available Checklist options WebList
isDisplayed() Check that Checklist is displayed boolean
check(String.../TEnum/TEnum.../int/int...) Check specified checkboxes and uncheck others void
checkAll() Check all checkboxes in checklist void
checked() Get selected checkbox values List
is() Get select assert ChecklistAssert
listEnabled() Get enabled checkboxes List
listDisabled() Get disabled checkboxes List
selected(UIElement/String) Get selected checkbox values boolean
selected() Get '{name}' selected option String
select(String.../TEnum/TEnum.../int/String/int...) Select checkboxes void
uncheck(String.../TEnum/TEnum.../int.../int) Uncheck specified checkboxes and check others void
uncheckAll() Uncheck all checkboxes in checklist void
setValue(String) Sets the value void
getStartIndex() Returns start index int
setStartIndex(int) Set start index void

Here is the list of some methods available for C# in JDI Light:

Method Description Return Type
AssertThat Get select assert SelectAssert
Check(params string[]/params int[]) Check checklist by values/indexes void
CheckAll() Check all checkboxes void
Checked() Get selected checkboxes from checklist value List<String>
Has Get select assert SelectAssert
Is Get select assert SelectAssert
ListEnabled() Get enabled checkboxes List<String>
ListDisabled() Get disabled checkboxes List<String>
Select(params string[]/params int[]) Select checklist by values/indexes void
Selected(string option) Checks whether a checkbox is selected bool
Size() Get checklist size int
Uncheck(params string[]/params int[]) Unselect checklist by values/indexes void
UncheckAll() Uncheck all checkboxes void
Values() Get checklist values List<String>

Test examples in Java

Test examples in C#

BDD Steps example

1.2.8 MultiSelector

MultiSelector – A graphical control element that allows user to make a multiple choice. MultiSelector is represented by the following class:

MultiSelector

@UI("#ages") // @FindBy(css = "#ages")  
public static MultiSelector ages;

@Test
public void selectTest() {
    ages.check("Electro", "Metalic");
    assertEquals(ages.checked(), asList("Electro", "Metalic"));
}

@Test
public void selectEnumTest() {
    ages.check(Wood, Steam);
    assertEquals(ages.checked(), asList("Steam", "Wood"));
}

@Test
public void selectNumTest() {
    ages.check(1, 5);
    assertEquals(ages.checked(), asList("Electro", "Wood"));
}
[Test]
public void MultiSelectByValues() 
{
    MyMultiSelector.Select(string[]);
}
[Test]
public void MultiSelectByIndexes() 
{
    MyMultiSelector.Select(int[]);
}
<select id="ages" multiple="" size="4">
    <option value="electro">Electro</option>
    <option value="steam" selected="">Steam</option>
    <option value="metalic">Metalic</option>
    <option value="dis" disabled="">Disabled</option>
    <option value="wood">Wood</option>
</select>

Here is a list of available methods and properties in C#:

Method / Property Description Return Type
AssertThat Property that returns object for work with assertions SelectAssert
Check(string/string[]/int/int[]/Enum[]) Select multiselector by values void
Checked() Get selected values List<string>
has() Returns object for work with assertions SelectAssert
Is Property that returns object for work with assertions SelectAssert
Selected() Get selected values string
shouldBe() Returns object for work with assertions SelectAssert
Uncheck(string[]/Enum[]/int[]) Select multiselector by values/indexes void
waitFor() Returns object for work with assertions SelectAssert

Here is the list of available methods/asserts in Java:

Method Description Return Type
select(String) Selects the value based on its visible text void
select(int) Selects the value based on its index void
assertThat() Returns object for work with assertions SelectAssert
check(String/String.../TEnum.../int...) Select multiselector by values void
checked() Get selected values List
is() Returns object for work with assertions UIMSelectAssert<?,?>
values() Get the elements values List
values(TextTypes) Get the elements values List
selected() Get selected element value by name String
selected(String) Checks if element selected by name boolean
listEnabled() Get the list of enabled elements List
listDisabled() Get the list of disabled elements List
setValue(String) Sets element value void
getValue() Gets element value String
getStartIndex() Returns start index int
SetStartIndex(int) Sets start index void
uncheck(String.../TEnum.../int...) Select multiselector by values/indices void
uncheckAll() Unchecks all elements void

Test examples in Java

Test examples in C#

BDD Steps example

1.3 HTML5 Composite elements

1.3.1 Section


  [FindBy(Id = "contact-form")]
  public Contact ContactSection;

  [FindBy(Css = ".footer-content")]
  public static Footer Footer;

  [FindBy(Css = ".uui-header")]
  public static Header Header;

  public JdiSearch Search;

  [FindBy(Id = "summary-block")]
  public Summary SummaryBlock;

  [Test]
  public void SectionTest()
  {
      var e = TestSite.HomePage.Get<Section>(By.CssSelector(".main-title"));
      Assert.AreEqual("EPAM FRAMEWORK WISHES…", e.Text);
      Assert.AreEqual("Section", e.Name);
      Assert.AreEqual(true, e.Displayed);
      Assert.AreEqual(true, e.Enabled);
      Assert.AreEqual(false, e.Hidden);
      Assert.AreEqual(By.CssSelector(".main-title"), e.Locator);
      Assert.AreEqual(false, e.Selected);
      Assert.AreEqual("h3", e.TagName);
  }

  [TestCaseSource(nameof(_contactSectionCases))]
  public void CustomContactSectionTest(string htmlElementToCheckName, string expectedLocator, string expectedName, string expectedSmartLocator)
  {
      var targetElement =
          ContactSection.GetType().GetMember(htmlElementToCheckName)[0].GetMemberValue(ContactSection) as UIElement;
      ContactSection.CheckInitializedElement(targetElement, expectedLocator, expectedName, expectedSmartLocator);
  }

  [Test]
  public void CustomFooterSectionTest()
  {
      FooterSection.CheckInitializedElement(FooterSection.AboutLink, "By.PartialLinkText: About", "AboutLink", null);            
  }

  [TestCaseSource(nameof(_headerSectionCases))]
  public void CustomHeaderSectionTest(string htmlElementToCheckName, string expectedLocator, string expectedName, string expectedSmartLocator)
  {
      var targetElement =
          HeaderSection.GetType().GetMember(htmlElementToCheckName)[0].GetMemberValue(HeaderSection) as UIElement;
      HeaderSection.CheckInitializedElement(targetElement, expectedLocator, expectedName, expectedSmartLocator);
  }

  [TestCaseSource(nameof(_jdiSearchSectionCases))]
  public void CustomJdiSearchSectionTest(string htmlElementToCheckName, string expectedLocator, string expectedName, string expectedSmartLocator)
  {
      var targetElement =
          JdiSearchSection.GetType().GetMember(htmlElementToCheckName)[0].GetMemberValue(JdiSearchSection) as UIElement;
      JdiSearchSection.CheckInitializedElement(targetElement, expectedLocator, expectedName, expectedSmartLocator);
  }

  [Test]
  public void CustomSummarySectionTest()
  {
      TestSite.MetalsColorsPage.Open();
      SummarySection.CheckInitializedElement(SummarySection.Calculate, "By.Id: calculate-button", "Calculate", null);
  }

  private static object[] _contactSectionCases =
  {
      new object[] { nameof(ContactSection.DescriptionField), "By.CssSelector: textarea#description", "Description", null },
      new object[] { nameof(ContactSection.FirstRoller), "By.XPath: .//a[@class='ui-slider-handle ui-state-default ui-corner-all' and position()=1]", "FirstRoller", null },
      new object[] { nameof(ContactSection.LastNameField), "By.CssSelector: input#last-name", "Last Name", null },
      new object[] { nameof(ContactSection.NameField), "By.CssSelector: input#name", "First Name", null },
      new object[] { nameof(ContactSection.SecondRoller), "By.XPath: .//a[@class='ui-slider-handle ui-state-default ui-corner-all' and position()=2]", "SecondRoller", null },
      new object[] { nameof(ContactSection.SubmitButton), "By.XPath: //button[@type='submit' and contains(., 'Submit')]", "SubmitButton", null },
  };

  private static object[] _headerSectionCases =
  {
      new object[] { nameof(HeaderSection.Image), "By.XPath: //img[@src=\"label/Logo_Epam_Color.svg\"]", "Image", null },
      new object[] { nameof(HeaderSection.Menu), "By.CssSelector: ul.uui-navigation.nav", "Menu", null },
      new object[] { nameof(HeaderSection.UserIcon), "By.CssSelector: #user-icon", "UserIcon", null },
      new object[] { nameof(HeaderSection.Search), "By.CssSelector: input#last-name", "Search", "By.Id: search" }
  };

  private static object[] _jdiSearchSectionCases =
  {
      new object[] { nameof(JdiSearchSection.SearchButton), "By.CssSelector: .search>.icon-search", "SearchButton", null },
      new object[] { nameof(JdiSearchSection.SearchButtonActive), "By.CssSelector: .icon-search.active", "SearchButtonActive", null },
      new object[] { nameof(JdiSearchSection.SearchInput), "By.CssSelector: .search-field input", "SearchInput", null },
  };

Section - Logical part of Web Page that contains other UI Elements

Section is located in the following classes:

   @UI(".someSectionUI") // @FindBy(css = ".someSectionUI")
    public static CustomSection customSectionUI;

   @Test(dataProvider = "customSectionWebElementDataProvider", dataProviderClass = CustomSectionDataProvider.class)
    public void customSectionWebElementTest(IBaseElement htmlElementToCheck, String expectedLocator, Object expectedParent, String expectedName) {
        checkInitializedElement(htmlElementToCheck, expectedLocator, expectedParent, expectedName);
    }

And here are methods available in Java:

Method Description Return Type
click() Makes a click void
click(ElementArea) Makes a click to area void
is() Returns object for work with assertions TextAssert

Test examples in Java

Test examples in C#

1.3.2 Form

Form – Logical part of a web page that represents an HTML form. Form consists of elements based on SetValue interface and buttons with submit function.

Form provides the fill, submit and verify/check functionality.

Form

<form class="form" id="contact-form">
  <div class="row overflow">
    <div class="col-sm-4">
      <div class="form-group form-group10">
        <label for="first-name">First Name</label>
        <input id="first-name" type="text" class="uui-form-element">
      </div>
    </div>
    <div class="col-sm-4">
      <div class="form-group form-group10">
        <label for="last-name">Last Name</label>
        <input id="last-name" type="text" class="uui-form-element">
      </div>
    </div>
    <div class="col-sm-4">
      <div class="form-group form-group10">
        <label for="position">Position</label>
        <input id="position" type="text" class="uui-form-element">
      </div>
    </div>
    <div class="col-sm-3">
      <div class="form-group form-group10 lower">
        <label for="passport">Passport</label>
        <input id="passport" type="checkbox" name="passport" class="uui-form-element">
      </div>
    </div>
    <div class="col-sm-4">
      <div class="form-group form-group10">
        <label for="passport-number">Number</label>
        <input id="passport-number" type="text" class="uui-form-element">
      </div>
    </div>
    <div class="col-sm-5">
      <div class="form-group form-group10">
        <label for="passport-seria">Seria</label>
        <input id="passport-seria" type="text" class="uui-form-element">
      </div>
    </div>
  </div>
  <div class="row">
    <div class="col-sm-4">
      <label for="gender">Gender</label>
      <select class="uui-form-element" ui="dropdown" id="gender">
        <option>Male</option>
        <option checked="">Female</option>
      </select>
    </div>
    <div class="col-sm-4">
      <label for="religion">Religion</label>
      <div class="form-group form-group10">
        <input list="religion-options" id="religion" placeholder="Religion" class="uui-form-element">
        <datalist id="religion-options">
          <option>Christian</option>
          <option>Muslims</option>
          <option>Induism</option>
          <option>Other</option>
        </datalist>
      </div>
    </div>
    <div class="col-sm-4">
      <label for="weather">Weather</label>
      <div class="form-group salad" ui="droplist" id="weather">
        <div class="dropdown salad">
          <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            <span class="caret"/>
          </button>
          <ul class="dropdown-menu" style="display: none;">
            <li>
              <a href="#" class="checkbox">
                <input type="checkbox" id="g5" class="uui-form-element blue">
                <label for="g5">Sun</label>
              </a>
            </li>
            <li>
              <a href="#" class="checkbox">
                <input type="checkbox" id="g6" class="uui-form-element blue">
                <label for="g6">Rain</label>
              </a>
            </li>
            <li>
              <a href="#" class="checkbox">
                <input type="checkbox" id="g7" class="uui-form-element blue">
                <label for="g7">Weather</label>
              </a>
            </li>
            <li>
              <a href="#" class="checkbox">
                <input type="checkbox" id="g8" class="uui-form-element blue">
                <label for="g8">Snow</label>
              </a>
            </li>
          </ul>
        </div>
      </div>
    </div>
  </div>
  <div class="row overflow">
    <div class="col-sm-12">
      <div class="form-group">
        <label for="description">Description</label>
        <textarea class="uui-form-element" rows="4" cols="10" id="description"/>
      </div>
      <div>
        <input id="accept-conditions" type="checkbox" name="accept-conditions">
        <label for="accept-conditions">Accept conditions</label>
      </div>
    </div>
    <div class="col-sm-12 text-right">
      <button class="uui-button dark-blue" type="submit">Submit</button>
    </div>
  </div>
</form>

Form is located in the following classes:

public class FormContactsTests implements TestsInit {
    @BeforeMethod
    public void before() {
        shouldBeLoggedIn();
        contactFormPage.shouldBeOpened();
        refresh();
    }

private static Contacts defaultContact() {
        return new Contacts().set(c -> {
            c.firstName = "Roman";
            c.lastName = "Iovlev";
            c.position = "ChiefQA";
            //c.passport = true;
            c.passportNumber = "4321";
            c.passportSeria = "123456";
            c.description = "JDI - awesome UI automation tool";
            c.acceptConditions = "true";
            c.gender = "Female";
            c.religion = "Other";
        });
    }

    @Test
    public void fillContactFormTest() {
        main.contactForm.description.getText();
        main.contactForm.fill(DEFAULT_CONTACT);
        main.contactForm.check(DEFAULT_CONTACT);
    }

    @Test
    public void submitTextToContactFormTest() {
        main.contactForm.submit("Roman");
        main.contactForm.check(ONLY_NAME_FILLED_DEFAULT_CONTACT);
        checkContactFormSubmitted();
    }

    @Test
    public void submitEntityToContactFormTest() {
        main.contactForm.submit(DEFAULT_CONTACT);
        main.contactForm.check(DEFAULT_CONTACT);
        checkContactFormSubmitted();
    }

    @Test
    public void submitTextToContactFormUsingCustomButtonTest() {
        main.contactForm.submit("Roman", "custom");
        main.contactForm.check(ONLY_NAME_FILLED_DEFAULT_CONTACT);
    }

    @Test
    public void submitTextToContactFormUsingNonExistentButtonTest() {
        main.contactFormCustom.submit("Roman", "nonExistent");
    }

    @Test
    public void submitEntityToContactFormUsingCustomButtonTest() {
        main.contactForm.submit(DEFAULT_CONTACT, "custom");
        main.contactForm.check(DEFAULT_CONTACT);
        checkContactFormSubmitted();
    }

    @Test
    public void submitEntityToContactFormUsingNonExistentButtonTest() {
        main.contactFormCustom.submit(DEFAULT_CONTACT, "nonExistent");
    }

    @Test
    public void plainSubmitTest() {
        main.contactForm.fill(DEFAULT_CONTACT);
        main.contactForm.submit();
        main.contactForm.check(DEFAULT_CONTACT);
        checkContactFormSubmitted();
    }

    @Test
    public void pressButtonTest() {
        main.contactFormCustom.fill(DEFAULT_CONTACT);
        main.contactFormCustom.pressButton("custom");
        main.contactFormCustom.check(DEFAULT_CONTACT);
        checkContactFormSubmitted();
    }

    @Test
    public void verifyMethodPositiveTest() {
        main.contactForm.fill(DEFAULT_CONTACT);
        List<String> verified = main.contactForm.verify(DEFAULT_CONTACT);
        assertEquals(verified.size(), 0);
    }

    @Test
    public void verifyMethodNegativeTest() {
        main.contactForm.fill(ALL_EXCEPT_NAME_FILLED_DEFAULT_CONTACT);
        List<String> verified = main.contactForm.verify(DEFAULT_CONTACT);
        assertEquals(verified.size(), 1);
        assertTrue(verified.get(0).contains("Roman"));
    }

    @Test
    public void checkMethodPositiveTest() {
        main.contactForm.fill(DEFAULT_CONTACT);
        main.contactForm.check(DEFAULT_CONTACT);
        assertEquals(main.contactForm.verify(DEFAULT_CONTACT).size(), 0);
    }

    @Test(expectedExceptions = RuntimeException.class)
    public void checkMethodNegativeTest() {
        main.contactForm.fill(ALL_EXCEPT_NAME_FILLED_DEFAULT_CONTACT);
        TIMEOUTS.element.set(1);
        main.contactForm.check(DEFAULT_CONTACT);
    }

    @Test
    public void sendMethodTest() {
        main.contactFormCustom.fill(DEFAULT_CONTACT);
        main.contactFormCustom.send();
        main.contactFormCustom.check(DEFAULT_CONTACT);
        checkContactFormSubmitted();
    }

    @Test
    public void sendEntityMethodTest() {
        main.contactFormCustom.send(DEFAULT_CONTACT);
        main.contactFormCustom.check(DEFAULT_CONTACT);
        checkContactFormSubmitted();
    }

    @Test
    public void addEntityMethodTest() {
        main.contactFormCustom.add(DEFAULT_CONTACT);
        main.contactFormCustom.check(DEFAULT_CONTACT);
        checkContactFormSubmitted();
    }

    @Test
    public void publishMethodTest() {
        main.contactFormCustom.publish(DEFAULT_CONTACT);
        main.contactFormCustom.check(DEFAULT_CONTACT);
        checkContactFormSubmitted();
    }

    @Test
    public void saveMethodTest() {
        main.contactFormCustom.save(DEFAULT_CONTACT);
        main.contactFormCustom.check(DEFAULT_CONTACT);
        checkContactFormSubmitted();
    }

    @Test
    public void updateMethodTest() {
        main.contactFormCustom.update(DEFAULT_CONTACT);
        main.contactFormCustom.check(DEFAULT_CONTACT);
        checkContactFormSubmitted();
    }

    @Test
    public void cancelMethodTest() {
        main.contactFormCustom.cancel(DEFAULT_CONTACT);
        main.contactFormCustom.check(DEFAULT_CONTACT);
        checkContactFormSubmitted();
    }

    @Test
    public void closeMethodTest() {
        main.contactFormCustom.close(DEFAULT_CONTACT);
        main.contactFormCustom.check(DEFAULT_CONTACT);
        checkContactFormSubmitted();
    }

    @Test
    public void backMethodTest() {
        main.contactFormCustom.back(DEFAULT_CONTACT);
        main.contactFormCustom.check(DEFAULT_CONTACT);
        checkContactFormSubmitted();
    }

    @Test
    public void selectMethodTest() {
        main.contactFormCustom.select(DEFAULT_CONTACT);
        main.contactFormCustom.check(DEFAULT_CONTACT);
        checkContactFormSubmitted();
    }

    @Test
    public void nextMethodTest() {
        main.contactFormCustom.next(DEFAULT_CONTACT);
        main.contactFormCustom.check(DEFAULT_CONTACT);
        checkContactFormSubmitted();
    }

    @Test
    public void searchMethodTest() {
        main.contactFormCustom.search(DEFAULT_CONTACT);
        main.contactFormCustom.check(DEFAULT_CONTACT);
        checkContactFormSubmitted();
    }

    @Test
    public void onlyMandatoryOptionTest() {
        main.contactFormCustom.onlyMandatory().fill(DEFAULT_CONTACT);
        main.contactFormCustom.check(ONLY_NAME_FILLED_DEFAULT_CONTACT);
        assertEquals(main.contactFormCustom.getFilter(), ALL);
    }

    @Test
    public void onlyOptionalOptionTest() {
        main.contactFormCustom.onlyOptional().fill(DEFAULT_CONTACT);
        main.contactFormCustom.check(ALL_EXCEPT_NAME_FILLED_DEFAULT_CONTACT);
        assertEquals(main.contactFormCustom.getFilter(), ALL);
    }

    @Test
    public void overriddenFillActionTest() {
        main.contactFormCustomFill.fill(DEFAULT_CONTACT);
        main.contactFormCustomFill.check(UPPER_CASE_NAME_CONTACT);
    }

    @Test
    public void uiFormTest() {
        main.contactFormUI.submit(DEFAULT_CONTACT);
        main.contactFormUI.check(DEFAULT_CONTACT);
        checkContactFormSubmitted();
    }

    @Test
    public void overriddenGetActionTest() {
        main.contactFormCustomGet.fill(DEFAULT_CONTACT);
        main.contactFormCustomGet.check(LOWER_CASE_NAME_CONTACT);
    }

    private void checkContactFormSubmitted() {
        lastLogEntry.assertThat()
                .text(containsString("submit:button clicked"));
    }
}

Form is parameterized by an entity that corresponds to the form. For example, a login form can be parameterized by a user entity. The entity should extend DataClass class (parameterized by the entity itself). The names of the entity fields should be exactly the same as the names of the form fields. All fields of the entity managed by the form should be Strings.


JDI Light allows you to define a form in three ways:

By creating a normal JDI Light Form - a typical Form in JDI with typified elements, @UI annotations, extending from Form.


By using smart locators for a JDI Light Form - Such Form utilizes the Smart locator functionality of JDI. In this case there is no need to explicitly define locators for the form elements as such locators can be obtained implicitly from field names using Smart locator functionality. See more details and examples for Smart locators in documentation


If a Form consists of only TextFields and Buttons, there is no need to define a Form UI Object. Such form can be added directly to the related page or to the root Site class. In this case the form field will be taken from the entity that the form is being parameterized by.


Form Filters

In Java, Form has a filter property that defines which form elements will be filled/submited or verified/checked. Filter can be set to either ALL, MANDATORY or OPTIONAL.

Based on this property, fill/submit and verify/check functions are applied to either all form elements or only mandatory (only optional) form elements.


Mandatory form fields should be marked with @Mandatory annotation. Optional form fields are the ones without @Mandatory annotation. ALL is the default Form option.


To set form filters as MANDATORY or OPTIONAL, onlyMandatory() and onlyOptional() methods should be used. They set the corresponding form filter option for a duration of a single action (all form action methods set the form filter option back to ALL).


Form Actions

In Java, Form also has a FILL_ACTION and GET_ACTION lambdas. This defines how the Form should be filled and verified. The default behavior defined in the Form class simply utilizes setValue(String value) method of the SetValue interface and getValue() method of the HasValue interface.

However, these lambdas can be redefined in the HtmlSettings class in order to customise the behavior for "non-text" form elements such as Checkboxes (the behavior of custom elements is defined by @FillValue and @VerifyValue annotations).

FILL_ACTION and GET_ACTION lambdas can also be further modified in order to customize Form behavior, but it is important to take into account that behavior defined in the HtmlSettings might be lost.

It is customary to reassign these lambdas before all the tests are run, for example in TestNG's @BeforeSuite method.


In Java, if fill/submit and verify/check methods need to be redefined for a specific form, it is possible to override fillAction() and getAction() for such form.


Methods available for Java in JDI Light:

Method Description Return Type
add(T) Fills all settable elements and clicks “add” Button or ”addButton” void
back(T) Fills all settable elements and clicks “back” Button or ”backButton” void
cancel(T) Fills all settable elements and clicks “cancel” Button or ”cancelButton” void
check(T) Verifies that form has been filled correctly. If not, throws an exception void
close(T) Fills all settable elements and clicks “close” Button or ”closeButton” void
fill(T) Fills all settable elements of the form that can be matched with fields of the input entity void
fillAction(Field, Object, Object, String) Defines the specifics of how form elements will be filled void
getAction(Field, Object, Object) Defines the specifics of how form elements will be obtained for verification and checks String
isDisplayed() Check that form is displayed boolean
isValid() Return that form is valid boolean
login() Clicks "login" Button or "loginButton" void
login(T) Fills all settable elements and clicks “login” Button or ”loginButton” void
loginAs(T) Fills all settable elements and clicks “login” Button or ”loginButton” void
next(T) Fills all settable elements and clicks “next” Button or ”nextButton” void
onlyMandatory() Sets form filter option to MANDATORY, meaning that only mandatory form elements are filled/submitted or verified/checked for the duration of a single form action void
onlyOptional() Sets form filter option to OPTIONAL, meaning that only optional form elements are filled/submitted or verified/checked for the duration of a single form action void
pressButton(String) Clicks “buttonName” Button or "buttonNamebutton". Allows different buttons to send one form, e.g. save/publish/cancel/search/update/... void
publish(T) Fills all settable elements and clicks “publish” Button or ”publishButton” void
save(T) Fills all settable elements and clicks “save” Button or ”saveButton” void
select(T) Fills all settable elements and clicks “select” Button or ”selectButton” void
search(T) Fills all settable elements and clicks “search” Button or ”searchButton” void
send() Sends the form by clicking “send” Button or "sendButton" void
send(T) Fills all settable elements and clicks “send” Button or ”sendButton” void
submit() Sends the form by clicking "submit" Button or "submitButton" void
submit(String) Fills first settable form field with value and clicks "submit" Button or "submitButton" void
submit(T) Fills all settable elements and clicks "submit" Button or "submitButton" void
submit(String, String) Fills first settable field with value and clicks “buttonName” Button or "buttonNamebutton" void
submit(T, String) Fills all settable elements and clicks “buttonName” Button or "buttonNamebutton" void
verify(T) Verifies that form has been filled correctly. If not, returns a list of keys where verification has failed List
update(T entity) Fills all settable elements and clicks “update” Button or ”updateButton” void

Test examples in Java

Test examples in C#

BDD Steps example

1.3.3 WebPage

WebPage - A parent Java class for all JDI Page Object classes. WebPage class extends DriverBase class, implements PageObject interface and contains a number of commonly used methods:

WebPage is provided by JDI Light in:

WebPage

Methods available for Java in JDI Light:

public class ActionsWebPageTests implements TestsInit {

    @BeforeMethod(alwaysRun = true)
    public void before() {
        shouldBeLoggedIn();
        contactFormPage.shouldBeOpened();
        leftMenu.select("Contact form");
    }

    @Test
    public void getUrlTest() {
        Assert.assertEquals(WebPage.getUrl(), "https://jdi-testing.github.io/jdi-light/contacts.html");
    }

    @Test
    public void getTitleTest() {
        Assert.assertEquals(WebPage.getTitle(), "Contact Form");
    }

    @Test
    public void checkOpenedTest() {
        contactFormPage.checkOpened();
    }


    @Test
    public void isOpenedTest() {
        Assert.assertTrue(contactFormPage.isOpened());
    }

    @Test
    public void scrollToBottomTest() {
        WebPage.scrollToBottom();
    }

    @Test
    public void scrollToTopTest() {
        WebPage.scrollToTop();
    }

    @Test
    public void scrollDownTest() {
        WebPage.scrollDown(30);
    }

    @Test
    public void scrollUpTest() {
        WebPage.scrollUp(20);
    }

    @Test
    public void scrollRightTest() {
        WebPage.scrollRight(10);
    }

    @Test
    public void scrollLeftTest() {
        WebPage.scrollLeft(5);
    }

    @Test
    public void toStringTest() {
        Assert.assertEquals(contactFormPage.toString(), "StaticSite.contactFormPage (url=https://jdi-testing.github.io/jdi-light/contacts.html; title=Contact Form)");
    }
}
Method Description Return Type
asForm() Returns new Form parameterized with local Name Form
back() Go back to previous page void
checkOpened() Checks that page has opened void
forward() Go forward to next page void
getCurrentPage() Returns the name of current Page String
getHtml() Gets HTML of current page String
getTitle() Returns Page Title String
getUrl() Returns URL of Page String
isOpened() Checks that page has opened boolean
open(String) Opens url specified for page void
open(Object...) Opens url specified for page with parameters void
openedPage(String) Checks that page has opened void
openSite() Opens a Site void
openSite(Class<?>) Parameterized Site opening void
openUrl(String) Opening WebPage with URL void
openUrl(String,String) Opening WebPage with URL and page name void
refresh() Reloads current page void
reload() Same as refresh() void
scroll(int,int) Scrolls to designated position void
scrollToTop() Scrolls to top void
scrollToBottom() Scrolls to bottom void
scrollDown(int) Scrolls down to designated position void
scrollUp(int) Scrolls up to designated position void
scrollRight(int) Scrolls right to designated position void
scrollLeft(int) Scrolls left to designated position void
setCurrentPage(WebPage) Instantiates the current Page with Name void
setUrl(String) Setting Up URL of Page void
setUrl(String,String,CheckTypes) Parameterized setting Up URL of Page void
shouldBeOpened() Checks that page has opened void
shouldBeOpened(Object) Checks that page has opened with parameters void
title() Returns new StringCheckType object with checked Title StringCheckType
toString() Overrides the Object class toString() method String
updatePageData(Url,Title) Setting Page URL and Title void
url() Returns new StringCheckType object with checked URL StringCheckType
visualWindowCheck() empty void
WebPage() Default constructor for WebPage class WebPage
WebPage(String) Parameterized URL constructor for WebPage class WebPage
WebPage(String,String) Parameterized with URL and Title constructor WebPage
windowScreenshot() Getting window screenshot,returns path or exception String
xOffset() Getting window x offset long
yOffset() Getting window y offset long
zoom(double) Zooms current page void
zoomLevel() Getting zoom level double

More than that, it has a nested StringCheckType class with the following methods:

Method Description Return Type
check() Checks that current page url/title equals to expected url/title boolean
contains() Checks that current page url/title contains expected url/title-matcher boolean
match() Checks that current page url/title matches to expected url/title-matcher boolean
StringCheckType(Supplier actual, String equals, String what) A parameterized constructor StringCheckType

Test examples in Java

BDD Steps example

2. Angular elements

2.1 Angular Common elements

2.1.1 Icons

Icon overview

Icon is located in the following class:

There is two different icons in Angular: Basic icon and SVG icon:

Basic icon Svg icon

    //@FindBy(id="#basic_icon")  
    @UI("#basic_icon")
    public static Icon basicIcon;

    //@FindBy(id="#svg_icon")  
    @UI("#svg_icon")
    public static Icon svgIcon;


    @Test
    public void checkBasicIconIsDisplayed() {
        basicIcon.show();
        basicIcon.is().displayed();
    }

    @Test
    public void checkSVGIconIsDisplayed() {
        svgIcon.show();
        svgIcon.is().displayed();
    }
<mat-icon _ngcontent-hkf-c334="" role="img" aria-hidden="false" aria-label="Example home icon" class="mat-icon notranslate material-icons mat-icon-no-color">home</mat-icon>
<mat-icon _ngcontent-hkf-c335="" role="img" svgicon="thumbs-up" aria-hidden="false" aria-label="Example thumbs up SVG icon" class="mat-icon notranslate mat-icon-no-color"><svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" fit="" preserveAspectRatio="xMidYMid meet" focusable="false">
    <path d="M0 0h24v24H0z" fill="none"></path>
    <path d="M1 21h4V9H1v12zm22-11c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.59 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-1.91l-.01-.01L23 10z"></path>
</svg></mat-icon>
Method Description Return Type
isDisplayed() Verify state boolean
show() Scroll to element void
Here you can find Icons tests

2.1.2 Progress spinner

Progress Spinner overview

Progress Spinner is located in the following class:

    //@FindBy(id="#basic-progress-spinner")    
    @UI("#basic-progress-spinner")
    public static Spinner basicProgressSpinner;

    //@FindBy(id="#show-spinner")    
    @UI("#show-spinner")
    public static Button showSpinner;


    @Test
    public void checkSpinnerAppearAndThenDisappear() {
        showSpinner.click();
        basicProgressSpinner.is().displayed();
        basicProgressSpinner.waitFor().hidden();
    }

Progress spinner

<mat-spinner _ngcontent-krq-c336="" role="progressbar" mode="indeterminate" class="mat-spinner mat-progress-spinner mat-primary mat-progress-spinner-indeterminate-animation" style="width: 100px; height: 100px;">
  <svg preserveAspectRatio="xMidYMid meet" focusable="false" viewBox="0 0 100 100" style="width: 100px; height: 100px;">
    <circle cx="50%" cy="50%" r="45" class="ng-star-inserted" style="animation-name: mat-progress-spinner-stroke-rotate-100; stroke-dasharray: 282.743px; stroke-width: 10%;"/>
  </svg>
</mat-spinner>
Method Description Return Type
isDisplayed() Verify state boolean
show() Scroll to element void
Here you can find Spinner tests

2.1.3 Slide toggle

Slide toggle overview

Slide toggle is located in the following class:

There is two different slide toggles in Angular: Basic and Configurable:

Basic toggle:

    //@FindBy(id="slide-toggles-basic")
    @UI("#slide-toggles-basic")
    public static SlideToggle basicSlideToggle;

    @Test
    public void basicTest() {
        basicSlideToggle.is().displayed();
        resultSlideToggle.is().displayed();
        checkedCheckbox.is().displayed();
        disableCheckbox.is().displayed();
        colorRadioButtons.is().displayed();
    }

    @Test
    public void basicToggleCheckedTest() {
        basicSlideToggle.check();
        basicSlideToggle.is().selected();
        basicSlideToggle.uncheck();
        basicSlideToggle.is().deselected();
    }

Basic slide toggle

<mat-slide-toggle _ngcontent-bco-c235="" class="mat-slide-toggle mat-accent mat-checked" id="mat-slide-toggle-1" tabindex="-1">
  <label class="mat-slide-toggle-label" for="mat-slide-toggle-1-input">
    <div class="mat-slide-toggle-bar">
      <input type="checkbox" role="switch" class="mat-slide-toggle-input cdk-visually-hidden" id="mat-slide-toggle-1-input" tabindex="0" aria-checked="true">
      <div class="mat-slide-toggle-thumb-container">
        <div class="mat-slide-toggle-thumb"/>
        <div mat-ripple="" class="mat-ripple mat-slide-toggle-ripple mat-focus-indicator">
          <div class="mat-ripple-element mat-slide-toggle-persistent-ripple"/>
        </div>
      </div>
    </div>
    <span class="mat-slide-toggle-content">
                <span style="display: none;">&nbsp;</span>Slide me!</span>
  </label>
</mat-slide-toggle>

Configurable slide toggle:

    //@FindBy(id="slide-toggles-configured") 
    @UI("#slide-toggles-configured")
    public static SlideToggle resultSlideToggle;

    @Test
    public void resultToggleColorTest() {
        disableCheckbox.uncheck();
        resultSlideToggle.check();
        primaryRadioButton.click();
        resultSlideToggle.has().cssClass("mat-primary");
        accentRadioButton.click();
        resultSlideToggle.has().cssClass("mat-accent");
        warningRadioButton.click();
        resultSlideToggle.has().cssClass("mat-warn");
    }

    @Test
    public void resultToggleCheckedTest() {
        resultSlideToggle.uncheck();
        checkedCheckbox.check();
        resultSlideToggle.is().selected();
        checkedCheckbox.uncheck();
        resultSlideToggle.is().deselected();
    }

    @Test
    public void resultToggleDisableTest() {
        disableCheckbox.check();
        resultSlideToggle.is().disabled();
        disableCheckbox.uncheck();
        resultSlideToggle.is().enabled();
    }

Configurable slide toggle

<mat-card-content _ngcontent-noq-c236="" class="mat-card-content">
  <h4 _ngcontent-noq-c236="">Slider configuration</h4>
  <section _ngcontent-noq-c236="" class="example-section">
    <label _ngcontent-noq-c236="" class="example-margin">Color:</label>
    <mat-radio-group _ngcontent-noq-c236="" role="radiogroup" class="mat-radio-group ng-untouched ng-pristine ng-valid">
      <mat-radio-button _ngcontent-noq-c236="" value="primary" class="mat-radio-button example-margin mat-accent" tabindex="-1" id="mat-radio-13">
        <label class="mat-radio-label" for="mat-radio-13-input">
          <div class="mat-radio-container">
            <div class="mat-radio-outer-circle"/>
            <div class="mat-radio-inner-circle"/>
            <input type="radio" class="mat-radio-input cdk-visually-hidden" id="mat-radio-13-input" tabindex="0" name="mat-radio-group-11" value="primary">
            <div mat-ripple="" class="mat-ripple mat-radio-ripple mat-focus-indicator">
              <div class="mat-ripple-element mat-radio-persistent-ripple"/>
            </div>
          </div>
          <div class="mat-radio-label-content">
            <span style="display: none;">&nbsp;</span> Primary </div>
        </label>
      </mat-radio-button>
      <mat-radio-button _ngcontent-noq-c236="" value="accent" class="mat-radio-button example-margin mat-accent mat-radio-checked" tabindex="-1" id="mat-radio-14">
        <label class="mat-radio-label" for="mat-radio-14-input">
          <div class="mat-radio-container">
            <div class="mat-radio-outer-circle"/>
            <div class="mat-radio-inner-circle"/>
            <input type="radio" class="mat-radio-input cdk-visually-hidden" id="mat-radio-14-input" tabindex="0" name="mat-radio-group-11" value="accent">
            <div mat-ripple="" class="mat-ripple mat-radio-ripple mat-focus-indicator">
              <div class="mat-ripple-element mat-radio-persistent-ripple"/>
            </div>
          </div>
          <div class="mat-radio-label-content">
            <span style="display: none;">&nbsp;</span> Accent </div>
        </label>
      </mat-radio-button>
      <mat-radio-button _ngcontent-noq-c236="" value="warn" class="mat-radio-button example-margin mat-accent" tabindex="-1" id="mat-radio-15">
        <label class="mat-radio-label" for="mat-radio-15-input">
          <div class="mat-radio-container">
            <div class="mat-radio-outer-circle"/>
            <div class="mat-radio-inner-circle"/>
            <input type="radio" class="mat-radio-input cdk-visually-hidden" id="mat-radio-15-input" tabindex="0" name="mat-radio-group-11" value="warn">
            <div mat-ripple="" class="mat-ripple mat-radio-ripple mat-focus-indicator">
              <div class="mat-ripple-element mat-radio-persistent-ripple"/>
            </div>
          </div>
          <div class="mat-radio-label-content">
            <span style="display: none;">&nbsp;</span> Warn </div>
        </label>
      </mat-radio-button>
    </mat-radio-group>
  </section>
  <section _ngcontent-noq-c236="" class="example-section">
    <mat-checkbox _ngcontent-noq-c236="" class="mat-checkbox example-margin mat-accent ng-untouched ng-pristine ng-valid" id="mat-checkbox-6">
      <label class="mat-checkbox-layout" for="mat-checkbox-6-input">
        <div class="mat-checkbox-inner-container">
          <input type="checkbox" class="mat-checkbox-input cdk-visually-hidden" id="mat-checkbox-6-input" tabindex="0" aria-checked="false">
          <div matripple="" class="mat-ripple mat-checkbox-ripple mat-focus-indicator">
            <div class="mat-ripple-element mat-checkbox-persistent-ripple"/>
          </div>
          <div class="mat-checkbox-frame"/>
          <div class="mat-checkbox-background">
            <svg version="1.1" focusable="false" viewBox="0 0 24 24" xml:space="preserve" class="mat-checkbox-checkmark">
                                            <path fill="none" stroke="white" d="M4.1,12.7 9,17.6 20.3,6.3" class="mat-checkbox-checkmark-path"/>
                                        </svg>
            <div class="mat-checkbox-mixedmark"/>
          </div>
        </div>
        <span class="mat-checkbox-label">
                                    <span style="display: none;">&nbsp;</span>Checked</span>
      </label>
    </mat-checkbox>
  </section>
  <section _ngcontent-noq-c236="" class="example-section">
    <mat-checkbox _ngcontent-noq-c236="" class="mat-checkbox example-margin mat-accent ng-untouched ng-pristine ng-valid" id="mat-checkbox-7">
      <label class="mat-checkbox-layout" for="mat-checkbox-7-input">
        <div class="mat-checkbox-inner-container">
          <input type="checkbox" class="mat-checkbox-input cdk-visually-hidden" id="mat-checkbox-7-input" tabindex="0" aria-checked="false">
          <div matripple="" class="mat-ripple mat-checkbox-ripple mat-focus-indicator">
            <div class="mat-ripple-element mat-checkbox-persistent-ripple"/>
          </div>
          <div class="mat-checkbox-frame"/>
          <div class="mat-checkbox-background">
            <svg version="1.1" focusable="false" viewBox="0 0 24 24" xml:space="preserve" class="mat-checkbox-checkmark">
                                                <path fill="none" stroke="white" d="M4.1,12.7 9,17.6 20.3,6.3" class="mat-checkbox-checkmark-path"/>
                                            </svg>
            <div class="mat-checkbox-mixedmark"/>
          </div>
        </div>
        <span class="mat-checkbox-label">
                                        <span style="display: none;">&nbsp;</span>Disabled</span>
      </label>
    </mat-checkbox>
  </section>
</mat-card-content>

List of some available Slide toggle methods:

Method Description Return Type
check() Check element void
uncheck() Uncheck element void
isEnabled() Verify state boolean
isDisabled() Verify state boolean
isDisplayed() Verify state boolean
isSelected() Verify state boolean
selected() Verify state boolean
deselected() Verify state boolean
click() Click element void
hasClass() Verify element class boolean
Here you can find Slide toggle tests

2.1.4 Checkbox

Checkbox overview

Checkbox is located in the following class:

There is two different checkboxes in Angular: Basic and Configurable.

See examples with HTML code describing datepicker elements.

  //@FindBy(id="basic-checkbox")
  @UI("basic-checkbox")
  public static Checkbox basicCheckbox;

  @Test
  public void checkLabelValue() {
      basicCheckbox.label().has().value("Check me!");
      resultCheckbox.label().has().value("I'm a checkbox");
  }

  @Test
  public void basicCheckboxValidation() {
      basicCheckbox.is().displayed().and().enabled().and().deselected();
  }

  @Test
  public void checkBasicCheckbox() {
      basicCheckbox.check();
      basicCheckbox.is().selected();
  }

Basic checkbox

<section class="example-section">
  <mat-checkbox id="basic-checkbox">Check me!</mat-checkbox>
</section>
  //@FindBy(id="checked-checkbox")
  @UI("checked-checkbox")
  public static Checkbox checkedCheckbox;

  //@FindBy(id="indeterminate-checkbox")
  @UI("indeterminate-checkbox")
  public static Checkbox indeterminateCheckbox;

  //@FindBy(id="disabled-checkbox")
  @UI("disabled-checkbox")
  public static Checkbox disabledCheckbox;

  //@FindBy(id="result-checkbox")
  @UI("result-checkbox")
  public static Checkbox resultCheckbox;

  //@FindBy(id="align-before-radio-button")
  @UI("align-before-radio-button")
  public static Button alignBeforeRadioButton;

  //@FindBy(id="align-after-radio-button")
  @UI("align-after-radio-button")
  public static Button alignAfterRadioButton;

  @Test
  public void indeterminateTest() {
      indeterminateCheckbox.click();
      resultCheckbox.is().indeterminate();
  }

  @Test
  public void disabledOption() {
      disabledCheckbox.click();
      resultCheckbox.is().disabled();
  }

  @Test
  public void configurableCheckboxTest() {
      indeterminateCheckbox.check();
      alignBeforeRadioButton.click();
      resultCheckbox.is().indeterminate().and().cssClass("mat-checkbox-label-before");
  }

Configurable checkbox

<mat-card>
  <mat-card-content>
    <h4>Checkbox configuration</h4>
    <section class="example-section">
      <mat-checkbox id="checked-checkbox" class="example-margin" [(ngModel)]="checked">
        Checked
      </mat-checkbox>
      <mat-checkbox id="indeterminate-checkbox" class="example-margin" [(ngModel)]="indeterminate">
        Indeterminate
      </mat-checkbox>
    </section>
    <section class="example-section">
      <label class="example-margin">Align:</label>
      <mat-radio-group [(ngModel)]="labelPosition">
        <mat-radio-button id="align-after-radio-button" class="example-margin" value="after">
          After
        </mat-radio-button>
        <mat-radio-button id="align-before-radio-button" class="example-margin" value="before">
          Before
        </mat-radio-button>
      </mat-radio-group>
    </section>
    <section class="example-section">
      <mat-checkbox id="disabled-checkbox" class="example-margin" [(ngModel)]="disabled">
        Disabled
      </mat-checkbox>
    </section>
  </mat-card-content>
</mat-card>
<mat-card class="result">
  <mat-card-content>
    <h4>Result</h4>
    <section class="example-section">
      <mat-checkbox
        id="result-checkbox"
        class="example-margin"
        [(ngModel)]="checked"
        [(indeterminate)]="indeterminate"
        [labelPosition]="labelPosition"
        [disabled]="disabled">
        I'm a checkbox
      </mat-checkbox>
    </section>
  </mat-card-content>
</mat-card>

List of some available Checkbox methods:

Method Description Return Type
is() Assert action CheckboxAssert
check() Check element void
uncheck() Uncheck element void
click() Click on element void
isSelected() Shows that Checkbox has selected boolean
isEnabled() Shows that Checkbox has enabled boolean
isDisabled() Shows that Checkbox has disabled boolean
isIndeterminate() Shows that Checkbox has indeterminate boolean
label() Get element label Label
Here you can find Checkbox tests

2.1.5 Inputs

Input overview

Input is located in the following class:

There are eight different inputs in Angular:

Basic inputs:

    //@FindBy(id="inputs_basic_food")
    @UI("#inputs_basic_food")
    public static TextField foodBasicInput;

    //@FindBy(id="inputs_basic_comment")
    @UI("#inputs_basic_comment")
    public static TextField leaveACommentBasicInput;

    @Test
    public void basicInputTest() {
        foodBasicInput.isDisplayed();
        foodBasicInput.clear();
        foodBasicInput.setText("Lasagna");
        foodBasicInput.is().text("Lasagna");
        foodBasicInput.clear();
        foodBasicInput.sendKeys("Ice Cream");
        foodBasicInput.is().text(containsString("Ice"));

        leaveACommentBasicInput.isDisplayed();
        leaveACommentBasicInput.sendKeys("Delicious");
        leaveACommentBasicInput.is().text("Delicious");
    }

Basic inputs

<input _ngcontent-ohc-c255="" matinput="" id="inputs_basic_food" placeholder="Ex. Pizza" value="Sushi" class="mat-input-element mat-form-field-autofill-control ng-tns-c94-34 cdk-text-field-autofill-monitored" aria-invalid="false" aria-required="false">

Input with a custom ErrorStateMatcher:

    //@FindBy(id="inputs_errorStateMatcher_email")
    @UI("#inputs_errorStateMatcher_email")
    public static TextField emailErrorStateMatcherInput;

    //@FindBy(id="inputs_errorStateMatcher_message")
    @UI("#inputs_errorStateMatcher_message")
    public static Text errorStateMatcherMessageInput;

    @Test
    public void inputWithACustomErrorStateMatcherTest() {
        emailErrorStateMatcherInput.isDisplayed();
        emailErrorStateMatcherInput.sendKeys("test");
        errorStateMatcherMessageInput.is().text("Please enter a valid email address");
    }

Input with a custom ErrorStateMatcher

<input _ngcontent-ohc-c256="" matinput="" id="inputs_errorStateMatcher_email" placeholder="Ex. pat@example.com" class="mat-input-element mat-form-field-autofill-control ng-tns-c94-39 cdk-text-field-autofill-monitored ng-untouched ng-pristine ng-invalid" aria-describedby="mat-hint-3" aria-invalid="false" aria-required="false">

Auto-resizing textarea:

    //@FindBy(id="inputs_autosize_textarea")
    @UI("#inputs_autosize_textarea")
    public static TextArea autoSizeTextArea;

    @Test
    public void autoResizingTextAreaTest() {
        autoSizeTextArea.isDisplayed();
        autoSizeTextArea.setLines("line1", "line2");
        autoSizeTextArea.addNewLine("line3");
        autoSizeTextArea.is().text("line1\nline2\nline3");
        autoSizeTextArea.clear();
        autoSizeTextArea.is().text("");
        autoSizeTextArea.setText("TextArea");
        autoSizeTextArea.is().text(containsString("Text"));
    }

Auto-resizing textarea

<textarea _ngcontent-ohc-c257="" rows="1" matinput="" id="inputs_autosize_textarea" cdktextareaautosize="" cdkautosizeminrows="1" cdkautosizemaxrows="5" class="mat-input-element mat-form-field-autofill-control cdk-textarea-autosize ng-tns-c94-42 cdk-text-field-autofill-monitored" aria-invalid="false" aria-required="false" style="min-height: 18px; max-height: 90px; height: 18px;"></textarea>

Input with a clear button:

    //@FindBy(id="inputs_clearable_textbox")
    @UI("#inputs_clearable_textbox")
    public static TextArea clearableInput;

    //@FindBy(id="inputs_clearable_button")
    @UI("#inputs_clearable_button")
    public static Button clearableInputButton;

    @Test
    public void clearableInputTest() {
        clearableInput.isDisplayed();
        clearableInput.clear();
        clearableInput.sendKeys("test");
        clearableInputButton.isDisplayed();
        clearableInputButton.click();
        clearableInput.is().text("");
    }

Input with a clear button

<input _ngcontent-ohc-c258="" matinput="" id="inputs_clearable_textbox" type="text" class="mat-input-element mat-form-field-autofill-control ng-tns-c94-43 cdk-text-field-autofill-monitored ng-untouched ng-pristine ng-valid" aria-invalid="false" aria-required="false">
<button _ngcontent-ohc-c258="" mat-button="" id="inputs_clearable_button" matsuffix="" mat-icon-button="" aria-label="Clear" class="mat-focus-indicator mat-button mat-icon-button mat-button-base ng-tns-c94-43 ng-star-inserted">
        <span class="mat-button-wrapper">
            <mat-icon _ngcontent-ohc-c258="" role="img" class="mat-icon notranslate material-icons mat-icon-no-color" aria-hidden="true">close</mat-icon>
        </span>
  <div matripple="" class="mat-ripple mat-button-ripple mat-button-ripple-round"/>
  <div class="mat-button-focus-overlay"/>
</button>

Input with error messages:

    //@FindBy(id="inputs_error_email")
    @UI("#inputs_error_email")
    public static TextField emailInput;

    //@FindBy(id="inputs_error_message")
    @UI("#inputs_error_message")
    public static Text errorMessageInput;

    @Test
    public void inputWithErrorMessagesTest() {
        emailInput.isDisplayed();
        emailInput.sendKeys("test");
        emailInput.sendKeys(Keys.ENTER);
        errorMessageInput.isDisplayed();
        errorMessageInput.is().text("Please enter a valid email address");
    }

Input with error messages

<input _ngcontent-ohc-c259="" matinput="" id="inputs_error_email" placeholder="Ex. pat@example.com" class="mat-input-element mat-form-field-autofill-control ng-tns-c94-44 cdk-text-field-autofill-monitored ng-untouched ng-pristine ng-invalid" aria-invalid="false" aria-required="false">

Inputs in a form:

    //@FindBy(css="input-form-example form")
    @UI("input-form-example form")
    public static InputsForm inputsForm;

     @Test
    public void inputsInAFormTest() {
        inputsForm.fill(DEFAULT_USER);
        inputsForm.firstName.is().text("Long");
        inputsForm.lastName.is().text("Dinh");
        inputsForm.address.is().text("259 Tran Hung Dao Street");
        inputsForm.address2.is().text("Ward Co Giang, District 1");
        inputsForm.city.is().text("Ho Chi Minh");
        inputsForm.state.is().text("Ho Chi Minh");
        inputsForm.postalCode.is().text("70000");
    }

Inputs in a form

<form _ngcontent-sod-c260="" novalidate="" class="example-form ng-untouched ng-pristine ng-valid"></form>

Input with hints:

    //@FindBy(id="inputs_hints_message")
    @UI("#inputs_hints_message")
    public static TextField messageHintInput;

    //@FindBy(id="inputs_hints_text")
    @UI("#inputs_hints_text")
    public static Text messageHint;

    //@FindBy(id="inputs_hints_counter")
    @UI("#inputs_hints_counter")
    public static Text messageCounterHint;

    @Test
    public void inputWithHintsTest() {
        messageHintInput.isDisplayed();
        messageHintInput.sendKeys("test");
        messageHint.isDisplayed();
        messageHint.is().text("Don't disclose personal info");
        messageCounterHint.isDisplayed();
        messageCounterHint.is().text("4 / 256");
    }

Input with hints

<input _ngcontent-ohc-c261="" matinput="" id="inputs_hints_message" maxlength="256" placeholder="Ex. I need help with..." class="mat-input-element mat-form-field-autofill-control ng-tns-c94-53 cdk-text-field-autofill-monitored" aria-describedby="inputs_hints_text inputs_hints_counter" aria-invalid="false" aria-required="false">
<mat-hint _ngcontent-ohc-c261="" id="inputs_hints_text" class="mat-hint ng-tns-c94-53"><strong _ngcontent-ohc-c261="">Don't disclose personal info</strong></mat-hint>

Input with prefixes and suffixes:

    //@FindBy(id="inputs_prefixes")
    @UI("#inputs_prefixes")
    public static Text prefixInput;

    //@FindBy(id="inputs_suffixes")
    @UI("#inputs_suffixes")
    public static Icon suffixInput;

    //@FindBy(id="inputs_prefixes_suffixes_phone")
    @UI("#inputs_prefixes_suffixes_phone")
    public static TextField telephoneInput;

    @Test
    public void inputWithPrefixesAndSuffixesTest() {
        prefixInput.isDisplayed();
        suffixInput.isDisplayed();
        telephoneInput.isDisplayed();
        telephoneInput.sendKeys("0123456789");
        telephoneInput.clear();
        telephoneInput.is().text("");
    }

Input with prefixes and suffixes

<span _ngcontent-ohc-c262="" matprefix="" id="inputs_prefixes" class="ng-tns-c94-54">+1 &nbsp;</span>
<input _ngcontent-ohc-c262="" type="tel" matinput="" id="inputs_prefixes_suffixes_phone" placeholder="555-555-1234" class="mat-input-element mat-form-field-autofill-control ng-tns-c94-54 cdk-text-field-autofill-monitored" aria-invalid="false" aria-required="false">
<mat-icon _ngcontent-ohc-c262="" role="img" matsuffix="" id="inputs_suffixes" class="mat-icon notranslate material-icons mat-icon-no-color ng-tns-c94-54" aria-hidden="true">edit</mat-icon>

List of available methods:

TextField:

Method Description Return Type
getText() returns text from the text field String
getValue() returns text from the text field String
setValue(String) returns text from the text field void
is() property that returns object for work with assertions TextAssert

TextArea:

Method Description Return Type
setLines(String...) Add lines as one string with '\n' delimiter void
getText() Returns lines dividing text using '\n' List
addNewLine(String) add line to the already existing void
cols() returns value of cols attribute int
rows() returns value of rows attribute int
getText() returns text from the textarea String
getValue() returns text from the textarea String
maxlength() returns value of maxlength attribute int
minlengt() returns value of minlength attribute int
setValue(String) returns text from the text field void
is() property that returns object for work with assertions TextAssert
Java tests examples

2.1.6 Toolbar

Toolbar overview

"mat-toolbar" is a container for headers, titles, or actions.

There is two different toolbars in Angular: Single row and Multiple row.

    /**@FindBy(id = "toolbar-basic") public static ToolbarSection toolbarSection;*/
    @UI("#toolbar-basic")
    public static TextArea toolbarTextArea;
    public static Text toolbarTextArea;

    /**@FindBy(id = "toolbar-table") public static ToolbarSection toolbarSection;*/
    @UI("#toolbar-table")
    public static Table toolbarTable;

    /**@FindBy(css = "#toolbar-table span:not(.example-spacer)") public static ToolbarSection toolbarSection;*/
    @UI("#toolbar-table span:not(.example-spacer)") 
    public static JList<Text> toolbarRowsElementsWithText;

    @Test
    public void basicToolbarTest() {
        String textForTest = "My App";
        String classForTest = "mat-toolbar";
        toolbarTextArea.is().displayed();
        toolbarTable.has().cssClass(classForTest);
        toolbarTextArea.is().text(containsString(textForTest));
    }

    @Test
    public void multiRowToolbarTest() {
        String classForTest = "mat-toolbar";
        List<String> listForTest = Arrays.asList("Custom Toolbar", "Second Line", "Third Line");
        toolbarTable.is().displayed();
        toolbarTable.has().cssClass(classForTest);
        toolbarRowsElementsWithText.is().values(listForTest);
    }

    @Test
    public void multiRowToolbarColorTest() {
        String colorForTest = "primary";
        toolbarTable.has().attr("color", colorForTest);
    }

Toolbar examples

<mat-toolbar _ngcontent-duh-c290="" id="toolbar-basic" class="mat-toolbar mat-toolbar-single-row">My App</mat-toolbar>
<mat-toolbar _ngcontent-duh-c291="" id="toolbar-table" color="primary" class="mat-toolbar mat-primary mat-toolbar-multiple-rows"><mat-toolbar-row _ngcontent-duh-c291="" class="mat-toolbar-row"><span _ngcontent-duh-c291="">Custom Toolbar</span></mat-toolbar-row><mat-toolbar-row _ngcontent-duh-c291="" class="mat-toolbar-row"><span _ngcontent-duh-c291="">Second Line</span><span _ngcontent-duh-c291="" class="example-spacer"></span><mat-icon _ngcontent-duh-c291="" role="img" aria-hidden="false" aria-label="Example user verified icon" class="mat-icon notranslate example-icon material-icons mat-icon-no-color">verified_user</mat-icon></mat-toolbar-row><mat-toolbar-row _ngcontent-duh-c291="" class="mat-toolbar-row"><span _ngcontent-duh-c291="">Third Line</span><span _ngcontent-duh-c291="" class="example-spacer"></span><mat-icon _ngcontent-duh-c291="" role="img" aria-hidden="false" aria-label="Example heart icon" class="mat-icon notranslate example-icon material-icons mat-icon-no-color">favorite</mat-icon><mat-icon _ngcontent-duh-c291="" role="img" aria-hidden="false" aria-label="Example delete icon" class="mat-icon notranslate example-icon material-icons mat-icon-no-color">delete</mat-icon></mat-toolbar-row></mat-toolbar>
Method Description Return Type
hasClass() Match passed value with the element class boolean
values() Assert that values are the same List
has() assert that element has attribute boolean
attr() Check whether an element has attribute of specified name and with given value IsAssert
is() Assert action TextAssert
displayed() Check that element is displayed TextAssert
Here you can find Toolbar tests

2.1.7 Basic Button

Button overview

Basic Button is located in the following class:

The angular Button:

    //@FindBy(id="basic-buttons-label")
    @UI("#basic-buttons-label")
    public static Button basicBasicButton;

    //@FindBy(id="basic-primary-button")
    @UI("#basic-primary-button")
    public static Button basicPrimaryButton;

    @Test
    public void clickTest() {
        basicBasicButton.click();
        basicBasicButton.has().cssClass(FOCUSED_CLASS);
        basicButtonsSection.basicButtonsLabel.is().has().text(containsString(BASIC_TEXT));
    }

    @Test
    public void clickWithMoveTest() {
        basicWarnButton.click(ElementArea.TOP_LEFT);
        basicWarnButton.has().cssClass(FOCUSED_CLASS);
        basicButtonsSection.basicButtonsLabel.is().has().text(containsString(WARN_TEXT));
    }

    @Test
    public void disableButtonTest() {
        basicDisabledButton.is().disabled();
    }

    @Test
    public void assertValidationTest() {
        basicBasicButton.assertThat().text(is(BASIC_TEXT));
        basicPrimaryButton.assertThat().text(is(PRIMARY_TEXT));
        basicAccentButton.assertThat().text(is(ACCENT_TEXT));
        basicWarnButton.assertThat().text(is(WARN_TEXT));
        basicDisabledButton.assertThat().text(is(DISABLED_TEXT));
        basicLinkButton.assertThat().text(is(LINK_TEXT));
    }

    @Test
    public void isValidationTest() {
        basicWarnButton.is().displayed();
        basicWarnButton.is().enabled();
        basicWarnButton.is().text(is(WARN_TEXT));
        basicWarnButton.is().text(containsString(WARN_TEXT));
        assertThat(basicWarnButton.core().css("font-size"), is("14px"));
        basicWarnButton.assertThat().displayed()
                .and().text(is(WARN_TEXT))
                .core()
                .css("font-size", is("14px"))
                .and()
                .cssClass("mat-button")
                .and()
                .attr("type")
                .tag(is("button"));
        basicDisabledButton.is().text(containsString(DISABLED_TEXT));
        basicDisabledButton.is().disabled();
    }

Button

<button _ngcontent-jos-c358="" mat-raised-button="" color="primary" id="raised-primary-button" class="mat-focus-indicator mat-raised-button mat-button-base mat-primary" ng-reflect-color="primary">
    <span class="mat-button-wrapper">Primary</span>
    <div matripple="" class="mat-ripple mat-button-ripple" ng-reflect-disabled="false" ng-reflect-centered="false" ng-reflect-trigger="[object HTMLButtonElement]"></div>
    <div class="mat-button-focus-overlay"></div>
</button>
Method Description Return Type
getValue() Returns value String
is() Assert action TextAssert
Basic Button java tests examples

2.1.8 Button toggle

Button toggle overview

Button toggle is based on Basic Button. Basic Button is located in the following class:

Button toggle located in the following class:

There are two different button toggles in Angular: Basic and Exclusive:

    //@FindBy(id = "mat-button-toggle-group-font")
    @UI("#mat-button-toggle-group-font")
    public static ButtonToggle basicButtonToggle;

    @Test
    public void verifyButtonToggle() {
        basicButtonToggle.is().displayed();
        basicButtonToggle.is().enabled();
        String ITALIC = "italic";
        basicButtonToggle.clickButtonToggleByValue(ITALIC);
        basicButtonToggle.is().assertButtonToggleIsSelected(ITALIC);
        basicButtonToggle.is().assertButtonToggleButtonIsPressed(ITALIC);
        basicButtonToggle.is().assertButtonToggleButtonHasText(ITALIC);
    }

    @Test
    public void verifyButtonToggleCombineSelection() {
        String BOLD = "bold";
        basicButtonToggle.clickButtonToggleByValue(BOLD);
        String UNDERLINE = "underline";
        basicButtonToggle.clickButtonToggleByValue(UNDERLINE);
        basicButtonToggle.is().assertButtonToggleIsSelected(BOLD);
        basicButtonToggle.is().assertButtonToggleIsSelected(UNDERLINE);
        basicButtonToggle.clickButtonToggleByValue(BOLD);
        basicButtonToggle.is().assertButtonToggleIsNotSelected(BOLD);
    }

Basic button toggle

<mat-button-toggle _ngcontent-eoo-c327="" value="underline" id="underline-button-toggle" class="mat-button-toggle mat-focus-indicator mat-button-toggle-appearance-standard" tabindex="-1">
    <button type="button" class="mat-button-toggle-button mat-focus-indicator" tabindex="0" aria-pressed="false">
        <div class="mat-button-toggle-label-content">Underline</div>
    </button>
    <div class="mat-button-toggle-focus-overlay"></div>
    <div matripple="" class="mat-ripple mat-button-toggle-ripple"></div>
</mat-button-toggle>

Exclusive button toggle:

    //@FindBy(id = "mat-button-toggle-group-align")
    @UI("#mat-button-toggle-group-align")  
    public static ButtonToggle basicButtonToggleAlign;

    //@FindBy(css = "div.example-selected-value")
    @UI("div.example-selected-value")
    public static Text selectedValue;

    @Test
    public void verifyExclusiveButtonToggle() {
        String LEFT = "left";
        basicButtonToggleAlign.is().displayed();
        basicButtonToggleAlign.is().enabled();
        basicButtonToggleAlign.clickButtonToggleByValue(LEFT);
        basicButtonToggleAlign.is().assertButtonToggleIsSelected(LEFT);
        selectedValue.has().text("Selected value: left");
    }

    @Test
    public void verifyExclusiveButtonToggleSeparateSelection() {
        String CENTER = "center";
        String LEFT = "left";
        String RIGHT = "right";
        basicButtonToggleAlign.clickButtonToggleByValue(CENTER);
        basicButtonToggleAlign.clickButtonToggleByValue(RIGHT);
        basicButtonToggleAlign.clickButtonToggleByValue(LEFT);
        basicButtonToggleAlign.is().assertButtonToggleIsSelected(LEFT);
        basicButtonToggleAlign.is().assertButtonToggleIsNotSelected(RIGHT);
        basicButtonToggleAlign.is().assertButtonToggleIsNotSelected(CENTER);
    }

Exclusive button toggle

<mat-button-toggle _ngcontent-pwh-c328="" value="left" aria-label="Text align left" id="left-align-button-toggle" class="mat-button-toggle mat-focus-indicator mat-button-toggle-appearance-standard" tabindex="-1">
    <button type="button" class="mat-button-toggle-button mat-focus-indicator"  tabindex="0" aria-pressed="false" name="mat-button-toggle-group-7" aria-label="Text align left">
        <div class="mat-button-toggle-label-content"><mat-icon _ngcontent-pwh-c328="" role="img" class="mat-icon notranslate material-icons mat-icon-no-color" aria-hidden="true">format_align_left</mat-icon></div>
    </button>
    <div class="mat-button-toggle-focus-overlay"></div>
    <div matripple="" class="mat-ripple mat-button-toggle-ripple"></div>
</mat-button-toggle>

List of available methods:

Method Description Return Type
clickButtonToggleByValue(String) Click required button void
clickButtonToggleByValue(String) is button pressed boolean
buttonToggleHasText(String) Does button has text boolean
isButtonToggleSelected(String) Is button toggle selected boolean
is() Assert action ButtonToggleAssert
Here you can find Button toggle tests

2.1.9 Badge

Badge overview

Badge is located in the following class:

Badge

  //@FindBy(css = "#text-with-badge span") 
  @UI("#text-with-badge span") 
  public static Badge textWithBadge;

  //@FindBy(css = "#button-with-left-badge span:not(.mat-button-wrapper)") 
  @UI("#button-with-left-badge span:not(.mat-button-wrapper)") 
  public static Badge buttonWithBadge;

  //@FindBy(css = "#icon-with-badge span") 
  @UI("#icon-with-badge span") 
  public static Badge iconWithBadge;

  @Test
  public void basicBadgeTest() {
      textWithBadge.show();
      textWithBadge.badge().is().displayed();
      textWithBadge.badge().has().text("4");
      textWithBadge.has().color("Violet");
  }

  @Test
  public void buttonBadgeTest() {
      buttonWithBadge.show();
      buttonWithBadge.badge().is().displayed();
      buttonWithBadge.badge().has().text("8");
      buttonWithBadge.has().color("Yellow");
  }

  @Test
  public void iconBadgeTest() {
      iconWithBadge.show();
      iconWithBadge.badge().is().displayed();
      iconWithBadge.badge().has().text("15");
      iconWithBadge.has().color("Red");
  }
<span _ngcontent-iwc-c329="" matbadge="4" matbadgeoverlap="false" id="text-with-badge" class="mat-badge mat-badge-above mat-badge-after mat-badge-medium">
    "Text with a badge"
    <span _ngcontent-iwc-c329="" id="mat-badge-content-0" class="mat-badge-content mat-badge-active">4</span>
</span>
Method Description Return Type
is() Assert action BadgeAssert
badge() Get badge UIElement
color(String) Check that color is correct boolean
Here you can find Badge tests

2.1.10 Progress bar

Progress bar overview

Progress bar is located in the following class:

There is 5 different progress bars in Angular: Buffer, Determinate, Indeterminate, Query and Configurable:

Buffer progress bar:

  //@FindBy(css = "#show-buffer-progress-bar-button")
  @UI("#show-buffer-progress-bar-button")
  public static Button showBufferProgressBarButton;

  //@FindBy(css = "#mat-progress-bar-buffer")
  @UI("#mat-progress-bar-buffer")
  public static ProgressBar matProgressBarBuffer;

  @Test
  public void verifyBufferProgressBarTest() throws Exception {
      showBufferProgressBarButton.click();
      matProgressBarBuffer.shouldBe().displayed();
      matProgressBarBuffer.show();
      matProgressBarBuffer.shouldBe().visible();
      matProgressBarBuffer.has().mode(BUFFER);
      matProgressBarBuffer.has().value(0);
      matProgressBarBuffer.has().bufferValue(0.0);
      matProgressBarBuffer.has().max(100);
      matProgressBarBuffer.has().min(0);
      matProgressBarBuffer.has().color(BLUE);
      matProgressBarBuffer.is().disappear(5);
  }

Buffer progress bar

<progress-bar-buffer-example _nghost-pnn-c338="" ng-version="9.1.0">
    <h2 _ngcontent-pnn-c338="" class="example-h2">
        <a _ngcontent-pnn-c338="" href="https://material.angular.io/components/progress-bar/overview#buffer"> Buffer progress-bar </a>
    </h2>
    <button _ngcontent-pnn-c338="" mat-raised-button="" id="show-buffer-progress-bar-button" class="mat-focus-indicator mat-raised-button mat-button-base">
        <span class="mat-button-wrapper"> Show progress-bar for 5 seconds
</span>
        <div matripple="" class="mat-ripple mat-button-ripple"/>
        <div class="mat-button-focus-overlay"/>
    </button>
    <div _ngcontent-pnn-c338="" hidden="">
        <mat-progress-bar _ngcontent-pnn-c338="" role="progressbar" aria-valuemin="0" aria-valuemax="100" id="mat-progress-bar-buffer" mode="buffer" class="mat-progress-bar mat-primary" aria-valuenow="0">
            <svg width="100%" height="4" focusable="false" class="mat-progress-bar-background mat-progress-bar-element">
                <defs>
                    <pattern x="4" y="0" width="8" height="4" patternUnits="userSpaceOnUse" id="mat-progress-bar-0">
                        <circle cx="2" cy="2" r="2"/>
                    </pattern>
                </defs>
                <rect width="100%" height="100%" fill="url('/jdi-light/angular.html#mat-progress-bar-0')"/>
            </svg>
            <div class="mat-progress-bar-buffer mat-progress-bar-element" style="transform: scaleX(0);"/>
            <div class="mat-progress-bar-primary mat-progress-bar-fill mat-progress-bar-element" style="transform: scaleX(0);"/>
            <div class="mat-progress-bar-secondary mat-progress-bar-fill mat-progress-bar-element"/>
        </mat-progress-bar>
    </div>
</progress-bar-buffer-example>

Determinate progress bar:

  //@FindBy(css = "#mat-progress-bar-determinate")
  @UI("#mat-progress-bar-determinate")
  public static ProgressBar matProgressBarDeterminate;

  @Test
  public void verifyDeterminateProgressBarTest() throws Exception {
      matProgressBarDeterminate.shouldBe().displayed();
      matProgressBarDeterminate.show();
      matProgressBarDeterminate.shouldBe().visible();
      matProgressBarDeterminate.has().mode(DETERMINATE);
      matProgressBarDeterminate.has().value(40);
      matProgressBarDeterminate.has().max(100);
      matProgressBarDeterminate.has().min(0);
      matProgressBarDeterminate.has().color(BLUE);
  }

Determinate progress bar

<progress-bar-determinate-example _nghost-pnn-c339="" ng-version="9.1.0">
    <h2 _ngcontent-pnn-c339="" class="example-h2">
        <a _ngcontent-pnn-c339="" href="https://material.angular.io/components/progress-bar/overview#determinate"> Determinate progress-bar </a>
    </h2>
    <mat-progress-bar _ngcontent-pnn-c339="" role="progressbar" aria-valuemin="0" aria-valuemax="100" id="mat-progress-bar-determinate" mode="determinate" value="40" class="mat-progress-bar mat-primary" aria-valuenow="40">
        <svg width="100%" height="4" focusable="false" class="mat-progress-bar-background mat-progress-bar-element">
            <defs>
                <pattern x="4" y="0" width="8" height="4" patternUnits="userSpaceOnUse" id="mat-progress-bar-1">
                    <circle cx="2" cy="2" r="2"/>
                </pattern>
            </defs>
            <rect width="100%" height="100%" fill="url('/jdi-light/angular.html#mat-progress-bar-1')"/>
        </svg>
        <div class="mat-progress-bar-buffer mat-progress-bar-element"/>
        <div class="mat-progress-bar-primary mat-progress-bar-fill mat-progress-bar-element" style="transform: scaleX(0.4);"/>
        <div class="mat-progress-bar-secondary mat-progress-bar-fill mat-progress-bar-element"/>
    </mat-progress-bar>
</progress-bar-determinate-example>

Indeterminate progress bar:

  //@FindBy(css = "#show-indeterminate-progress-bar-button")
  @UI("#show-indeterminate-progress-bar-button")
  public static Button showIndeterminateProgressBarButton;

  //@FindBy(css = "#mat-progress-bar-indeterminate")
  @UI("#mat-progress-bar-indeterminate")
  public static ProgressBar matProgressBarIndeterminate;

  @Test
  public void verifyIndeterminateProgressBarTest() {
      showIndeterminateProgressBarButton.click();
      matProgressBarIndeterminate.shouldBe().displayed();
      matProgressBarIndeterminate.show();
      matProgressBarIndeterminate.shouldBe().visible();
      matProgressBarIndeterminate.has().mode(INDETERMINATE);
      matProgressBarIndeterminate.has().max(100);
      matProgressBarIndeterminate.has().min(0);
      matProgressBarIndeterminate.has().color(BLUE);
      matProgressBarIndeterminate.is().disappear(5);
  }

Indeterminate progress bar

<progress-bar-query-example class="ng-star-inserted">
    <mat-progress-bar role="progressbar" aria-valuemin="0" aria-valuemax="100" tabindex="-1" mode="query" class="mat-progress-bar mat-primary">
        <div aria-hidden="true">
            <svg width="100%" height="4" focusable="false" class="mat-progress-bar-background mat-progress-bar-element">
                <defs>
                    <pattern x="4" y="0" width="8" height="4" patternUnits="userSpaceOnUse" id="mat-progress-bar-3">
                        <circle cx="2" cy="2" r="2"/>
                    </pattern>
                </defs>
                <rect width="100%" height="100%" fill="url('/components/progress-bar/overview#mat-progress-bar-3')"/>
            </svg>
            <div class="mat-progress-bar-buffer mat-progress-bar-element"/>
            <div class="mat-progress-bar-primary mat-progress-bar-fill mat-progress-bar-element" style="transform: scale3d(0, 1, 1);"/>
            <div class="mat-progress-bar-secondary mat-progress-bar-fill mat-progress-bar-element"/>
        </div>
    </mat-progress-bar>
</progress-bar-query-example>

Query progress bar:

  //@FindBy(css = "#mat-progress-bar-query")
  @UI("#mat-progress-bar-query")
  public static ProgressBar matProgressBarQuery;

  @Test
  public void verifyQueryProgressBarTest() {
      matProgressBarQuery.shouldBe().displayed();
      matProgressBarQuery.show();
      matProgressBarQuery.shouldBe().visible();
      matProgressBarQuery.has().mode(QUERY);
      matProgressBarQuery.has().max(100);
      matProgressBarQuery.has().min(0);
      matProgressBarQuery.has().color(BLUE);
  }

Query progress bar

<progress-bar-determinate-example _nghost-pnn-c339="" ng-version="9.1.0">
    <h2 _ngcontent-pnn-c339="" class="example-h2">
        <a _ngcontent-pnn-c339="" href="https://material.angular.io/components/progress-bar/overview#determinate"> Determinate progress-bar </a>
    </h2>
    <mat-progress-bar _ngcontent-pnn-c339="" role="progressbar" aria-valuemin="0" aria-valuemax="100" id="mat-progress-bar-determinate" mode="determinate" value="40" class="mat-progress-bar mat-primary" aria-valuenow="40">
        <svg width="100%" height="4" focusable="false" class="mat-progress-bar-background mat-progress-bar-element">
            <defs>
                <pattern x="4" y="0" width="8" height="4" patternUnits="userSpaceOnUse" id="mat-progress-bar-1">
                    <circle cx="2" cy="2" r="2"/>
                </pattern>
            </defs>
            <rect width="100%" height="100%" fill="url('/jdi-light/angular.html#mat-progress-bar-1')"/>
        </svg>
        <div class="mat-progress-bar-buffer mat-progress-bar-element"/>
        <div class="mat-progress-bar-primary mat-progress-bar-fill mat-progress-bar-element" style="transform: scaleX(0.4);"/>
        <div class="mat-progress-bar-secondary mat-progress-bar-fill mat-progress-bar-element"/>
    </mat-progress-bar>
</progress-bar-determinate-example>

Configurable progress bar:

  //@FindBy(css = "#mat-progress-bar-configurable")
  @UI("#mat-progress-bar-configurable")
  public static ProgressBar matProgressBarConfigurable;

  @Test
  public void verifyBasicConfigurableProgressBarTest() throws Exception {
      matProgressBarConfigurable.shouldBe().displayed();
      matProgressBarConfigurable.show();
      matProgressBarConfigurable.shouldBe().visible();
      matProgressBarConfigurable.has().mode(DETERMINATE);
      matProgressBarConfigurable.has().value(50);
      matProgressBarConfigurable.has().max(100);
      matProgressBarConfigurable.has().min(0);
      matProgressBarConfigurable.has().color(BLUE);
  }

Configurable progress bar

<progress-bar-configurable-example _nghost-pnn-c342="" ng-version="9.1.0"><h2 _ngcontent-pnn-c342="" class="example-h2">Configurable progress bar</h2><mat-card _ngcontent-pnn-c342="" class="mat-card mat-focus-indicator"><mat-card-content _ngcontent-pnn-c342="" class="mat-card-content"><h4 _ngcontent-pnn-c342="">Progress bar configuration</h4><section _ngcontent-pnn-c342="" class="example-section"><label _ngcontent-pnn-c342="" class="example-margin">Color:</label><mat-radio-group _ngcontent-pnn-c342="" role="radiogroup" class="mat-radio-group ng-untouched ng-pristine ng-valid"><mat-radio-button _ngcontent-pnn-c342="" id="progress-bars-primary-color-radio" value="primary" class="mat-radio-button example-margin mat-accent mat-radio-checked" tabindex="-1"><label class="mat-radio-label" for="progress-bars-primary-color-radio-input"><div class="mat-radio-container"><div class="mat-radio-outer-circle"></div><div class="mat-radio-inner-circle"></div><input type="radio" class="mat-radio-input cdk-visually-hidden" id="progress-bars-primary-color-radio-input" tabindex="0" name="mat-radio-group-33" value="primary"><div mat-ripple="" class="mat-ripple mat-radio-ripple mat-focus-indicator"><div class="mat-ripple-element mat-radio-persistent-ripple"></div></div></div><div class="mat-radio-label-content"><span style="display: none;">&nbsp;</span> Primary </div></label></mat-radio-button><mat-radio-button _ngcontent-pnn-c342="" id="progress-bars-accent-color-radio" value="accent" class="mat-radio-button example-margin mat-accent" tabindex="-1"><label class="mat-radio-label" for="progress-bars-accent-color-radio-input"><div class="mat-radio-container"><div class="mat-radio-outer-circle"></div><div class="mat-radio-inner-circle"></div><input type="radio" class="mat-radio-input cdk-visually-hidden" id="progress-bars-accent-color-radio-input" tabindex="0" name="mat-radio-group-33" value="accent"><div mat-ripple="" class="mat-ripple mat-radio-ripple mat-focus-indicator"><div class="mat-ripple-element mat-radio-persistent-ripple"></div></div></div><div class="mat-radio-label-content"><span style="display: none;">&nbsp;</span> Accent </div></label></mat-radio-button><mat-radio-button _ngcontent-pnn-c342="" id="progress-bars-warn-color-radio" value="warn" class="mat-radio-button example-margin mat-accent" tabindex="-1"><label class="mat-radio-label" for="progress-bars-warn-color-radio-input"><div class="mat-radio-container"><div class="mat-radio-outer-circle"></div><div class="mat-radio-inner-circle"></div><input type="radio" class="mat-radio-input cdk-visually-hidden" id="progress-bars-warn-color-radio-input" tabindex="0" name="mat-radio-group-33" value="warn"><div mat-ripple="" class="mat-ripple mat-radio-ripple mat-focus-indicator"><div class="mat-ripple-element mat-radio-persistent-ripple"></div></div></div><div class="mat-radio-label-content"><span style="display: none;">&nbsp;</span> Warn </div></label></mat-radio-button></mat-radio-group></section><section _ngcontent-pnn-c342="" class="example-section"><label _ngcontent-pnn-c342="" class="example-margin">Mode:</label><mat-radio-group _ngcontent-pnn-c342="" role="radiogroup" class="mat-radio-group ng-untouched ng-pristine ng-valid"><mat-radio-button _ngcontent-pnn-c342="" id="progress-bars-determinate-mode-radio" value="determinate" class="mat-radio-button example-margin mat-accent mat-radio-checked" tabindex="-1"><label class="mat-radio-label" for="progress-bars-determinate-mode-radio-input"><div class="mat-radio-container"><div class="mat-radio-outer-circle"></div><div class="mat-radio-inner-circle"></div><input type="radio" class="mat-radio-input cdk-visually-hidden" id="progress-bars-determinate-mode-radio-input" tabindex="0" name="mat-radio-group-37" value="determinate"><div mat-ripple="" class="mat-ripple mat-radio-ripple mat-focus-indicator"><div class="mat-ripple-element mat-radio-persistent-ripple"></div></div></div><div class="mat-radio-label-content"><span style="display: none;">&nbsp;</span> Determinate </div></label></mat-radio-button><mat-radio-button _ngcontent-pnn-c342="" id="progress-bars-indeterminate-mode-radio" value="indeterminate" class="mat-radio-button example-margin mat-accent" tabindex="-1"><label class="mat-radio-label" for="progress-bars-indeterminate-mode-radio-input"><div class="mat-radio-container"><div class="mat-radio-outer-circle"></div><div class="mat-radio-inner-circle"></div><input type="radio" class="mat-radio-input cdk-visually-hidden" id="progress-bars-indeterminate-mode-radio-input" tabindex="0" name="mat-radio-group-37" value="indeterminate"><div mat-ripple="" class="mat-ripple mat-radio-ripple mat-focus-indicator"><div class="mat-ripple-element mat-radio-persistent-ripple"></div></div></div><div class="mat-radio-label-content"><span style="display: none;">&nbsp;</span> Indeterminate </div></label></mat-radio-button><mat-radio-button _ngcontent-pnn-c342="" id="progress-bars-buffer-mode-radio" value="buffer" class="mat-radio-button example-margin mat-accent" tabindex="-1"><label class="mat-radio-label" for="progress-bars-buffer-mode-radio-input"><div class="mat-radio-container"><div class="mat-radio-outer-circle"></div><div class="mat-radio-inner-circle"></div><input type="radio" class="mat-radio-input cdk-visually-hidden" id="progress-bars-buffer-mode-radio-input" tabindex="0" name="mat-radio-group-37" value="buffer"><div mat-ripple="" class="mat-ripple mat-radio-ripple mat-focus-indicator"><div class="mat-ripple-element mat-radio-persistent-ripple"></div></div></div><div class="mat-radio-label-content"><span style="display: none;">&nbsp;</span> Buffer </div></label></mat-radio-button><mat-radio-button _ngcontent-pnn-c342="" id="progress-bars-query-mode-radio" value="query" class="mat-radio-button example-margin mat-accent" tabindex="-1"><label class="mat-radio-label" for="progress-bars-query-mode-radio-input"><div class="mat-radio-container"><div class="mat-radio-outer-circle"></div><div class="mat-radio-inner-circle"></div><input type="radio" class="mat-radio-input cdk-visually-hidden" id="progress-bars-query-mode-radio-input" tabindex="0" name="mat-radio-group-37" value="query"><div mat-ripple="" class="mat-ripple mat-radio-ripple mat-focus-indicator"><div class="mat-ripple-element mat-radio-persistent-ripple"></div></div></div><div class="mat-radio-label-content"><span style="display: none;">&nbsp;</span> Query </div></label></mat-radio-button></mat-radio-group></section><section _ngcontent-pnn-c342="" class="example-section ng-star-inserted"><label _ngcontent-pnn-c342="" class="example-margin">Progress:</label><mat-slider _ngcontent-pnn-c342="" role="slider" id="progress-bars-progress-slider" class="mat-slider mat-focus-indicator example-margin mat-accent mat-slider-horizontal ng-untouched ng-pristine ng-valid" tabindex="0" aria-disabled="false" aria-valuemax="100" aria-valuemin="0" aria-valuenow="50" aria-orientation="horizontal"><div class="mat-slider-wrapper"><div class="mat-slider-track-wrapper"><div class="mat-slider-track-background" style="transform: translateX(0px) scale3d(0.5, 1, 1);"></div><div class="mat-slider-track-fill" style="transform: translateX(0px) scale3d(0.5, 1, 1);"></div></div><div class="mat-slider-ticks-container" style="transform: translateX(0%);"><div class="mat-slider-ticks" style="background-size: 0% 2px; transform: translateZ(0px) translateX(0%);"></div></div><div class="mat-slider-thumb-container" style="transform: translateX(-50%);"><div class="mat-slider-focus-ring"></div><div class="mat-slider-thumb"></div><div class="mat-slider-thumb-label"><span class="mat-slider-thumb-label-text">50</span></div></div></div></mat-slider></section><!----><!----></mat-card-content></mat-card><mat-card _ngcontent-pnn-c342="" class="mat-card mat-focus-indicator"><mat-card-content _ngcontent-pnn-c342="" class="mat-card-content"><h4 _ngcontent-pnn-c342="">Result</h4><section _ngcontent-pnn-c342="" class="example-section"><mat-progress-bar _ngcontent-pnn-c342="" role="progressbar" aria-valuemin="0" aria-valuemax="100" id="mat-progress-bar-configurable" class="mat-progress-bar example-margin mat-primary" aria-valuenow="50" mode="determinate"><svg width="100%" height="4" focusable="false" class="mat-progress-bar-background mat-progress-bar-element"><defs><pattern x="4" y="0" width="8" height="4" patternUnits="userSpaceOnUse" id="mat-progress-bar-4"><circle cx="2" cy="2" r="2"></circle></pattern></defs><rect width="100%" height="100%" fill="url('/jdi-light/angular.html#mat-progress-bar-4')"></rect></svg><div class="mat-progress-bar-buffer mat-progress-bar-element"></div><div class="mat-progress-bar-primary mat-progress-bar-fill mat-progress-bar-element" style="transform: scaleX(0.5);"></div><div class="mat-progress-bar-secondary mat-progress-bar-fill mat-progress-bar-element"></div></mat-progress-bar></section></mat-card-content></mat-card></progress-bar-configurable-example>

List of the available Progress bar methods:

Method Description Return Type
is() Assert action ProgressBarAssert
max() Get max limit int
min() Get min limit int
mode() Get mode value String
value() Get progress value int
getValue() Get progress value String
bufferValue() Assert action double
isVisible() Check if progress bar is visible boolean
Progress bar java tests examples

2.1.11 Slider

Slider overview

Progress bar locates in the following class:

There is 3 different sliders in Angular: Basic, Slider with custom thumb label formatting and Configurable:

Basic slider:

  //@FindBy(css = "#mat-slider-basic")
  @UI("#mat-slider-basic")
  public static Slider matSliderBasic;

  @Test
  public void sliderBasicGetValueTest() {
      matSliderBasic.show();
      matSliderBasic.has().value(0.0);
      matSliderBasic.setupValue(30);
      matSliderBasic.has().value(30.0);
  }

Basic slider

<slider-overview-example _nghost-ret-c263="" ng-version="9.1.0">
    <h2 _ngcontent-ret-c263="" class="example-h2">
        <a _ngcontent-ret-c263="" href="https://material.angular.io/components/slider/overview"> Basic slider </a>
    </h2>
    <mat-slider _ngcontent-ret-c263="" role="slider" id="mat-slider-basic" class="mat-slider mat-focus-indicator mat-accent mat-slider-horizontal mat-slider-min-value" tabindex="0" aria-disabled="false" aria-valuemax="100" aria-valuemin="0" aria-valuenow="0" aria-orientation="horizontal">
        <div class="mat-slider-wrapper">
            <div class="mat-slider-track-wrapper">
                <div class="mat-slider-track-background" style="transform: translateX(7px) scale3d(1, 1, 1);"/>
                <div class="mat-slider-track-fill" style="transform: translateX(-7px) scale3d(0, 1, 1); display: none;"/>
            </div>
            <div class="mat-slider-ticks-container" style="transform: translateX(0%);">
                <div class="mat-slider-ticks" style="background-size: 0% 2px; transform: translateZ(0px) translateX(0%); padding-left: 7px;"/>
            </div>
            <div class="mat-slider-thumb-container" style="transform: translateX(-100%);">
                <div class="mat-slider-focus-ring"/>
                <div class="mat-slider-thumb"/>
                <div class="mat-slider-thumb-label">
                    <span class="mat-slider-thumb-label-text">0</span>
                </div>
            </div>
        </div>
    </mat-slider>
</slider-overview-example>

Slider with custom thumb label formatting:

  //@FindBy(css = "#mat-slider-formatting")
  @UI("#mat-slider-formatting")
  public static Slider matSliderFormatting;

  @Test
  public void sliderFormattingGetValueTest() {
      matSliderFormatting.has().value(1.0);
      matSliderFormatting.show();
      matSliderFormatting.setupValue(2000);
      matSliderFormatting.has().value(2000.0);
  }

Slider with custom thumb label formatting

<slider-formatting-example _nghost-ret-c264="" ng-version="9.1.0">
    <h2 _ngcontent-ret-c264="" class="example-h2">
        <a _ngcontent-ret-c264="" href="https://material.angular.io/components/slider/overview#formatting-the-thumb-label"> Slider with custom thumb label formatting </a>
    </h2>
    <mat-slider _ngcontent-ret-c264="" role="slider" id="mat-slider-formatting" thumblabel="" tickinterval="1000" min="1" max="100000" class="mat-slider mat-focus-indicator mat-accent mat-slider-has-ticks mat-slider-horizontal mat-slider-thumb-label-showing mat-slider-min-value" tabindex="0" aria-disabled="false" aria-valuemax="100000" aria-valuemin="1" aria-valuenow="1" aria-orientation="horizontal">
        <div class="mat-slider-wrapper">
            <div class="mat-slider-track-wrapper">
                <div class="mat-slider-track-background" style="transform: translateX(0px) scale3d(1, 1, 1);"/>
                <div class="mat-slider-track-fill" style="transform: translateX(0px) scale3d(0, 1, 1); display: none;"/>
            </div>
            <div class="mat-slider-ticks-container" style="transform: translateX(-0.500005%);">
                <div class="mat-slider-ticks" style="background-size: 1.00001% 2px; transform: translateZ(0px) translateX(0.500005%);"/>
            </div>
            <div class="mat-slider-thumb-container" style="transform: translateX(-100%);">
                <div class="mat-slider-focus-ring"/>
                <div class="mat-slider-thumb"/>
                <div class="mat-slider-thumb-label">
                    <span class="mat-slider-thumb-label-text">1</span>
                </div>
            </div>
        </div>
    </mat-slider>
</slider-formatting-example>

Configurable slider:

  //@FindBy(css = "#mat-slider-configurable")
  @UI("#mat-slider-configurable")
  public static Slider matSliderConfigurable;

  @Test
  public void sliderConfigurableGetValueTest() {
      matSliderConfigurable.has().value(0.0);
      matSliderConfigurable.show();
      matSliderConfigurable.setupValue(60);
      matSliderConfigurable.has().value(60.0);
  }

  @Test
  public void sliderConfigurableSetupValueTest() {
      matSliderConfigurable.show();
      matSliderConfigurable.setupValue(35.5);
      matSliderConfigurable.has().value(35.5);
  }

Configurable slider

<slider-configurable-example _nghost-ret-c265="" ng-version="9.1.0">
    <h2 _ngcontent-ret-c265="" class="example-h2">Configurable slider</h2>
    <mat-card _ngcontent-ret-c265="" class="mat-card mat-focus-indicator">
        <mat-card-content _ngcontent-ret-c265="" class="mat-card-content">
            <h4 _ngcontent-ret-c265="">Slider configuration</h4>
            <section _ngcontent-ret-c265="" class="example-section">
                <mat-form-field _ngcontent-ret-c265="" class="mat-form-field example-margin ng-tns-c94-55 mat-primary mat-form-field-type-mat-input mat-form-field-appearance-fill mat-form-field-can-float mat-form-field-has-label ng-untouched ng-pristine ng-valid mat-form-field-should-float">
                    <div class="mat-form-field-wrapper ng-tns-c94-55">
                        <div class="mat-form-field-flex ng-tns-c94-55">
                            <div class="mat-form-field-infix ng-tns-c94-55">
                                <input _ngcontent-ret-c265="" matinput="" type="number" id="slider-configurable-value" class="mat-input-element mat-form-field-autofill-control ng-tns-c94-55 cdk-text-field-autofill-monitored ng-untouched ng-pristine ng-valid" aria-invalid="false" aria-required="false">
                                    <span class="mat-form-field-label-wrapper ng-tns-c94-55">
                                        <label class="mat-form-field-label ng-tns-c94-55 ng-star-inserted" id="mat-form-field-label-85" for="slider-configurable-value" aria-owns="slider-configurable-value">
                                            <mat-label _ngcontent-ret-c265="" class="ng-tns-c94-55 ng-star-inserted">Value</mat-label>
                                        </label>
                                    </span>
                                </div>
                            </div>
                            <div class="mat-form-field-underline ng-tns-c94-55 ng-star-inserted">
                                <span class="mat-form-field-ripple ng-tns-c94-55"/>
                            </div>
                            <div class="mat-form-field-subscript-wrapper ng-tns-c94-55">
                                <div class="mat-form-field-hint-wrapper ng-tns-c94-55 ng-trigger ng-trigger-transitionMessages ng-star-inserted" style="opacity: 1; transform: translateY(0%);">
                                    <div class="mat-form-field-hint-spacer ng-tns-c94-55"/>
                                </div>
                            </div>
                        </div>
                    </mat-form-field>
                    <mat-form-field _ngcontent-ret-c265="" class="mat-form-field example-margin ng-tns-c94-56 mat-primary mat-form-field-type-mat-input mat-form-field-appearance-fill mat-form-field-can-float mat-form-field-has-label ng-untouched ng-pristine ng-valid mat-form-field-should-float">
                        <div class="mat-form-field-wrapper ng-tns-c94-56">
                            <div class="mat-form-field-flex ng-tns-c94-56">
                                <div class="mat-form-field-infix ng-tns-c94-56">
                                    <input _ngcontent-ret-c265="" matinput="" type="number" id="slider-configurable-min" class="mat-input-element mat-form-field-autofill-control ng-tns-c94-56 cdk-text-field-autofill-monitored ng-untouched ng-pristine ng-valid" aria-invalid="false" aria-required="false">
                                        <span class="mat-form-field-label-wrapper ng-tns-c94-56">
                                            <label class="mat-form-field-label ng-tns-c94-56 ng-star-inserted" id="mat-form-field-label-87" for="slider-configurable-min" aria-owns="slider-configurable-min">
                                                <mat-label _ngcontent-ret-c265="" class="ng-tns-c94-56 ng-star-inserted">Min value</mat-label>
                                            </label>
                                        </span>
                                    </div>
                                </div>
                                <div class="mat-form-field-underline ng-tns-c94-56 ng-star-inserted">
                                    <span class="mat-form-field-ripple ng-tns-c94-56"/>
                                </div>
                                <div class="mat-form-field-subscript-wrapper ng-tns-c94-56">
                                    <div class="mat-form-field-hint-wrapper ng-tns-c94-56 ng-trigger ng-trigger-transitionMessages ng-star-inserted" style="opacity: 1; transform: translateY(0%);">
                                        <div class="mat-form-field-hint-spacer ng-tns-c94-56"/>
                                    </div>
                                </div>
                            </div>
                        </mat-form-field>
                        <mat-form-field _ngcontent-ret-c265="" class="mat-form-field example-margin ng-tns-c94-57 mat-primary mat-form-field-type-mat-input mat-form-field-appearance-fill mat-form-field-can-float mat-form-field-has-label ng-untouched ng-pristine ng-valid mat-form-field-should-float">
                            <div class="mat-form-field-wrapper ng-tns-c94-57">
                                <div class="mat-form-field-flex ng-tns-c94-57">
                                    <div class="mat-form-field-infix ng-tns-c94-57">
                                        <input _ngcontent-ret-c265="" matinput="" type="number" id="slider-configurable-max" class="mat-input-element mat-form-field-autofill-control ng-tns-c94-57 cdk-text-field-autofill-monitored ng-untouched ng-pristine ng-valid" aria-invalid="false" aria-required="false">
                                            <span class="mat-form-field-label-wrapper ng-tns-c94-57">
                                                <label class="mat-form-field-label ng-tns-c94-57 ng-star-inserted" id="mat-form-field-label-89" for="slider-configurable-max" aria-owns="slider-configurable-max">
                                                    <mat-label _ngcontent-ret-c265="" class="ng-tns-c94-57 ng-star-inserted">Max value</mat-label>
                                                </label>
                                            </span>
                                        </div>
                                    </div>
                                    <div class="mat-form-field-underline ng-tns-c94-57 ng-star-inserted">
                                        <span class="mat-form-field-ripple ng-tns-c94-57"/>
                                    </div>
                                    <div class="mat-form-field-subscript-wrapper ng-tns-c94-57">
                                        <div class="mat-form-field-hint-wrapper ng-tns-c94-57 ng-trigger ng-trigger-transitionMessages ng-star-inserted" style="opacity: 1; transform: translateY(0%);">
                                            <div class="mat-form-field-hint-spacer ng-tns-c94-57"/>
                                        </div>
                                    </div>
                                </div>
                            </mat-form-field>
                            <mat-form-field _ngcontent-ret-c265="" class="mat-form-field example-margin ng-tns-c94-58 mat-primary mat-form-field-type-mat-input mat-form-field-appearance-fill mat-form-field-can-float mat-form-field-has-label ng-untouched ng-pristine ng-valid mat-form-field-should-float">
                                <div class="mat-form-field-wrapper ng-tns-c94-58">
                                    <div class="mat-form-field-flex ng-tns-c94-58">
                                        <div class="mat-form-field-infix ng-tns-c94-58">
                                            <input _ngcontent-ret-c265="" matinput="" type="number" id="slider-configurable-step" class="mat-input-element mat-form-field-autofill-control ng-tns-c94-58 cdk-text-field-autofill-monitored ng-untouched ng-pristine ng-valid" aria-invalid="false" aria-required="false">
                                                <span class="mat-form-field-label-wrapper ng-tns-c94-58">
                                                    <label class="mat-form-field-label ng-tns-c94-58 ng-star-inserted" id="mat-form-field-label-91" for="slider-configurable-step" aria-owns="slider-configurable-step">
                                                        <mat-label _ngcontent-ret-c265="" class="ng-tns-c94-58 ng-star-inserted">Step size</mat-label>
                                                    </label>
                                                </span>
                                            </div>
                                        </div>
                                        <div class="mat-form-field-underline ng-tns-c94-58 ng-star-inserted">
                                            <span class="mat-form-field-ripple ng-tns-c94-58"/>
                                        </div>
                                        <div class="mat-form-field-subscript-wrapper ng-tns-c94-58">
                                            <div class="mat-form-field-hint-wrapper ng-tns-c94-58 ng-trigger ng-trigger-transitionMessages ng-star-inserted" style="opacity: 1; transform: translateY(0%);">
                                                <div class="mat-form-field-hint-spacer ng-tns-c94-58"/>
                                            </div>
                                        </div>
                                    </div>
                                </mat-form-field>
                            </section>
                            <section _ngcontent-ret-c265="" class="example-section">
                                <mat-checkbox _ngcontent-ret-c265="" id="slider-configurable-showTicks" class="mat-checkbox example-margin mat-accent ng-untouched ng-pristine ng-valid">
                                    <label class="mat-checkbox-layout" for="slider-configurable-showTicks-input">
                                        <div class="mat-checkbox-inner-container">
                                            <input type="checkbox" class="mat-checkbox-input cdk-visually-hidden" id="slider-configurable-showTicks-input" tabindex="0" aria-checked="false">
                                                <div matripple="" class="mat-ripple mat-checkbox-ripple mat-focus-indicator">
                                                    <div class="mat-ripple-element mat-checkbox-persistent-ripple"/>
                                                </div>
                                                <div class="mat-checkbox-frame"/>
                                                <div class="mat-checkbox-background">
                                                    <svg version="1.1" focusable="false" viewBox="0 0 24 24" xml:space="preserve" class="mat-checkbox-checkmark">
                                                        <path fill="none" stroke="white" d="M4.1,12.7 9,17.6 20.3,6.3" class="mat-checkbox-checkmark-path"/>
                                                    </svg>
                                                    <div class="mat-checkbox-mixedmark"/>
                                                </div>
                                            </div>
                                            <span class="mat-checkbox-label">
                                                <span style="display: none;">&nbsp;</span>Show ticks</span>
                                        </label>
                                    </mat-checkbox>
                                </section>
                                <section _ngcontent-ret-c265="" class="example-section">
                                    <mat-checkbox _ngcontent-ret-c265="" id="slider-configurable-thumb-label" class="mat-checkbox example-margin mat-accent ng-untouched ng-pristine ng-valid">
                                        <label class="mat-checkbox-layout" for="slider-configurable-thumb-label-input">
                                            <div class="mat-checkbox-inner-container">
                                                <input type="checkbox" class="mat-checkbox-input cdk-visually-hidden" id="slider-configurable-thumb-label-input" tabindex="0" aria-checked="false">
                                                    <div matripple="" class="mat-ripple mat-checkbox-ripple mat-focus-indicator">
                                                        <div class="mat-ripple-element mat-checkbox-persistent-ripple"/>
                                                    </div>
                                                    <div class="mat-checkbox-frame"/>
                                                    <div class="mat-checkbox-background">
                                                        <svg version="1.1" focusable="false" viewBox="0 0 24 24" xml:space="preserve" class="mat-checkbox-checkmark">
                                                            <path fill="none" stroke="white" d="M4.1,12.7 9,17.6 20.3,6.3" class="mat-checkbox-checkmark-path"/>
                                                        </svg>
                                                        <div class="mat-checkbox-mixedmark"/>
                                                    </div>
                                                </div>
                                                <span class="mat-checkbox-label">
                                                    <span style="display: none;">&nbsp;</span>Show thumb label</span>
                                            </label>
                                        </mat-checkbox>
                                    </section>
                                    <section _ngcontent-ret-c265="" class="example-section">
                                        <mat-checkbox _ngcontent-ret-c265="" id="slider-configurable-vertical" class="mat-checkbox example-margin mat-accent ng-untouched ng-pristine ng-valid">
                                            <label class="mat-checkbox-layout" for="slider-configurable-vertical-input">
                                                <div class="mat-checkbox-inner-container">
                                                    <input type="checkbox" class="mat-checkbox-input cdk-visually-hidden" id="slider-configurable-vertical-input" tabindex="0" aria-checked="false">
                                                        <div matripple="" class="mat-ripple mat-checkbox-ripple mat-focus-indicator">
                                                            <div class="mat-ripple-element mat-checkbox-persistent-ripple"/>
                                                        </div>
                                                        <div class="mat-checkbox-frame"/>
                                                        <div class="mat-checkbox-background">
                                                            <svg version="1.1" focusable="false" viewBox="0 0 24 24" xml:space="preserve" class="mat-checkbox-checkmark">
                                                                <path fill="none" stroke="white" d="M4.1,12.7 9,17.6 20.3,6.3" class="mat-checkbox-checkmark-path"/>
                                                            </svg>
                                                            <div class="mat-checkbox-mixedmark"/>
                                                        </div>
                                                    </div>
                                                    <span class="mat-checkbox-label">
                                                        <span style="display: none;">&nbsp;</span>Vertical</span>
                                                </label>
                                            </mat-checkbox>
                                            <mat-checkbox _ngcontent-ret-c265="" id="slider-configurable-invert" class="mat-checkbox example-margin mat-accent ng-untouched ng-pristine ng-valid">
                                                <label class="mat-checkbox-layout" for="slider-configurable-invert-input">
                                                    <div class="mat-checkbox-inner-container">
                                                        <input type="checkbox" class="mat-checkbox-input cdk-visually-hidden" id="slider-configurable-invert-input" tabindex="0" aria-checked="false">
                                                            <div matripple="" class="mat-ripple mat-checkbox-ripple mat-focus-indicator">
                                                                <div class="mat-ripple-element mat-checkbox-persistent-ripple"/>
                                                            </div>
                                                            <div class="mat-checkbox-frame"/>
                                                            <div class="mat-checkbox-background">
                                                                <svg version="1.1" focusable="false" viewBox="0 0 24 24" xml:space="preserve" class="mat-checkbox-checkmark">
                                                                    <path fill="none" stroke="white" d="M4.1,12.7 9,17.6 20.3,6.3" class="mat-checkbox-checkmark-path"/>
                                                                </svg>
                                                                <div class="mat-checkbox-mixedmark"/>
                                                            </div>
                                                        </div>
                                                        <span class="mat-checkbox-label">
                                                            <span style="display: none;">&nbsp;</span>Inverted</span>
                                                    </label>
                                                </mat-checkbox>
                                            </section>
                                            <section _ngcontent-ret-c265="" class="example-section">
                                                <mat-checkbox _ngcontent-ret-c265="" id="slider-configurable-disabled" class="mat-checkbox example-margin mat-accent ng-untouched ng-pristine ng-valid">
                                                    <label class="mat-checkbox-layout" for="slider-configurable-disabled-input">
                                                        <div class="mat-checkbox-inner-container">
                                                            <input type="checkbox" class="mat-checkbox-input cdk-visually-hidden" id="slider-configurable-disabled-input" tabindex="0" aria-checked="false">
                                                                <div matripple="" class="mat-ripple mat-checkbox-ripple mat-focus-indicator">
                                                                    <div class="mat-ripple-element mat-checkbox-persistent-ripple"/>
                                                                </div>
                                                                <div class="mat-checkbox-frame"/>
                                                                <div class="mat-checkbox-background">
                                                                    <svg version="1.1" focusable="false" viewBox="0 0 24 24" xml:space="preserve" class="mat-checkbox-checkmark">
                                                                        <path fill="none" stroke="white" d="M4.1,12.7 9,17.6 20.3,6.3" class="mat-checkbox-checkmark-path"/>
                                                                    </svg>
                                                                    <div class="mat-checkbox-mixedmark"/>
                                                                </div>
                                                            </div>
                                                            <span class="mat-checkbox-label">
                                                                <span style="display: none;">&nbsp;</span>Disabled</span>
                                                        </label>
                                                    </mat-checkbox>
                                                </section>
                                            </mat-card-content>
                                        </mat-card>
                                        <mat-card _ngcontent-ret-c265="" class="mat-card mat-focus-indicator example-result-card">
                                            <mat-card-content _ngcontent-ret-c265="" class="mat-card-content">
                                                <h4 _ngcontent-ret-c265="">Result</h4>
                                                <mat-slider _ngcontent-ret-c265="" role="slider" id="mat-slider-configurable" class="mat-slider mat-focus-indicator example-margin mat-accent mat-slider-horizontal mat-slider-min-value ng-untouched ng-pristine ng-valid" tabindex="0" aria-disabled="false" aria-valuemax="100" aria-valuemin="0" aria-valuenow="0" aria-orientation="horizontal">
                                                    <div class="mat-slider-wrapper">
                                                        <div class="mat-slider-track-wrapper">
                                                            <div class="mat-slider-track-background" style="transform: translateX(7px) scale3d(1, 1, 1);"/>
                                                            <div class="mat-slider-track-fill" style="transform: translateX(-7px) scale3d(0, 1, 1); display: none;"/>
                                                        </div>
                                                        <div class="mat-slider-ticks-container" style="transform: translateX(0%);">
                                                            <div class="mat-slider-ticks" style="background-size: 0% 2px; transform: translateZ(0px) translateX(0%); padding-left: 7px;"/>
                                                        </div>
                                                        <div class="mat-slider-thumb-container" style="transform: translateX(-100%);">
                                                            <div class="mat-slider-focus-ring"/>
                                                            <div class="mat-slider-thumb"/>
                                                            <div class="mat-slider-thumb-label">
                                                                <span class="mat-slider-thumb-label-text">0</span>
                                                            </div>
                                                        </div>
                                                    </div>
                                                </mat-slider>
                                            </mat-card-content>
                                        </mat-card>
                                    </slider-configurable-example>

List of the available Slider methods:

Method Description Return Type
min() get min limit double
max() get max limit double
value() get value double
orientation() Returns element orientation String
isInverted() check if inverted boolean
isThumbLabelDisplayed() is thumblabel displayed boolean
setValue(String) Set value void
moveRight() move carriage to right void
moveLeft() move carriage to left void
isDisabled() Is disabled boolean
isEnabled() Is enabled boolean
getValue() Returns value String
is() Assert action SliderAssert
has() Assert action SliderAssert
setupValue(double) Set value void
slide(double) Drag & drop based on percentage length void
Slider java tests examples

2.1.12 Tooltip

The Angular Material tooltip provides a text label that is displayed when the user hovers over or longpresses an element.

Tooltip overview

Tooltip is located in the following class:

  //FindBy(css = ".mat-tooltip") 
  @UI(".mat-tooltip")
  public static Tooltip tooltip;

  @Test
    public void basicTooltipTest() {
        basicTooltipButton.hover();
        tooltip.has().assertTooltipText("Petit a petit, l’oiseau fait son nid");
  }

  @Test
  public void customPositionTooltipTest() {
      Map<String, Tooltip.Position> position = new HashMap<>();
      position.put("after", Tooltip.Position.RIGHT);
      position.put("before", Tooltip.Position.LEFT);
      position.put("above", Tooltip.Position.ABOVE);
      position.put("below", Tooltip.Position.BELOW);
      position.put("left", Tooltip.Position.LEFT);
      position.put("right", Tooltip.Position.RIGHT);

      positionTooltipButton.show();

      position.forEach(
              (k, v) -> {
                  positionTooltipSelector.click();
                  (new MaterialSelectorContainer()).select(k);
                  positionTooltipButton.hover();
                  tooltip.has().assertTooltipPosition(v, positionTooltipButton);
              }
      );
  }

Tooltip

<button mat-raised-button
        matTooltip="Info about the action"
        aria-label="Button that displays a tooltip when focused or hovered over">
  Action
</button>

Method Description Return Type
text() Get text String
color() Get color String
position(UIBaseElement<?>) Get position relative to element Position
is() Assert action TooltipAssert
Here you can find Tooltip tests

2.1.13 Spinner

Tooltip overview

Spinner is located in the following class:

There is 2 different spinners in Angular: Basic and Configurable:

Basic progress spinner

  //FindBy(css = "#basic-progress-spinner") 
  @UI("#basic-progress-spinner")
  public static Spinner basicProgressSpinner;

  //FindBy(css = "#show-spinner") 
  @UI("#show-spinner") 
  public static Button showSpinner;

  @Test
  public void disappear() {
      showSpinner.click();
      basicProgressSpinner.waitFor().disappear();
  }

  @Test
  public void baseValidationTest() {
      showSpinner.show();
      showSpinner.click();
      baseValidation(basicProgressSpinner);
  }

  @Test
  public void checkSpinnerHidden() {
      showSpinner.click();
      basicProgressSpinner.assertThat().hidden();
  }
<progress-spinner-overview-example _nghost-prk-c338="" ng-version="9.1.0">
    <h2 _ngcontent-prk-c338="" class="example-h2">
        <a _ngcontent-prk-c338="" href="https://material.angular.io/components/progress-spinner/overview"> Basic progress-spinner </a>
    </h2>
    <button _ngcontent-prk-c338="" mat-raised-button="" id="show-spinner" class="mat-focus-indicator mat-raised-button mat-button-base">
        <span class="mat-button-wrapper"> Show progress-spinner for 5 seconds
</span>
        <div matripple="" class="mat-ripple mat-button-ripple"/>
        <div class="mat-button-focus-overlay"/>
    </button>
    <div _ngcontent-prk-c338="" hidden="">
        <mat-spinner _ngcontent-prk-c338="" role="progressbar" mode="indeterminate" id="basic-progress-spinner" class="mat-spinner mat-progress-spinner mat-primary mat-progress-spinner-indeterminate-animation" style="width: 100px; height: 100px;">
            <svg preserveAspectRatio="xMidYMid meet" focusable="false" viewBox="0 0 100 100" style="width: 100px; height: 100px;">
                <circle cx="50%" cy="50%" r="45" class="ng-star-inserted" style="animation-name: mat-progress-spinner-stroke-rotate-100; stroke-dasharray: 282.743px; stroke-width: 10%;"/>
                <!---->
                <!---->
            </svg>
        </mat-spinner>
    </div>
</progress-spinner-overview-example>
Method Description Return Type
is() Assert action UIAssert
click() Click action void
isDisplayed() Check that element is displayed boolean
isHidden() Check that element is hidden boolean
Here you can find Spinner tests

2.2 Angular Complex elements

2.2.1 Radio Buttons

Radio button overview

Element that can be represented with one or more clickable buttons aiming to choose only one button of the group.

Radio buttons locates in the following classes:

There are two different radio buttons types in Angular: Basic radios and Radios with NGmodel.

    //FindBy(id = "basic-radio-group")
    @UI("basic-radio-group")
    public static RadioButtons basicRadioGroup;

    //FindBy(id = "season-radio-group")
    @UI("season-radio-group")
    public static RadioButtons seasonRadioGroup;

    //FindBy(id = "your-favorit-season-text") 
    @UI("your-favorit-season-text") 
    public static Text yourFavoriteSeasonText;

    @Test
    public void basicRadioButtonsTest() {
        basicRadioGroup.is().displayed();
        basicRadioGroup.click("2");
        basicRadioGroup.click("1");
        basicRadioGroup.click("2");

        basicRadioGroup.is().checked("2");
        basicRadioGroup.is().notChecked("1");
    }

    @Test
    public void seasonsRadioButtonsTest() {
        seasonRadioGroup.is().displayed();
        seasonRadioGroup.click(SUMMER);
        seasonRadioGroup.click(WINTER);
        seasonRadioGroup.click(AUTUMN);

        seasonRadioGroup.click(SPRING);
        seasonRadioGroup.is().checked(SPRING);
        yourFavoriteSeasonText.has().text(format("Your favorite season is: %s", SPRING));

        seasonRadioGroup.is().notChecked(WINTER);
        seasonRadioGroup.is().notChecked(SUMMER);
        seasonRadioGroup.is().notChecked(AUTUMN);
    }

Basic radios

<mat-radio-group id="basic-radio-group" aria-label="Select an option"> 
<mat-radio-button id="{{'radio-option-one'}}" value="1">Option 1</mat-radio-button> 
<mat-radio-button id="{{'radio-option-two'}}" value="2">Option 2</mat-radio-button> 
</mat-radio-group>

Radios_with_ngmodel

<mat-radio-group id="season-radio-group" aria-labelledby="example-radio-group-label" class="example-radio-group" [(ngModel)]="favoriteSeason">
  <mat-radio-button id="{{'favorite-season-' + season.toLowerCase()}}" class="example-radio-button" *ngFor="let season of seasons" [value]="season">
    {{season}}
  </mat-radio-button>
</mat-radio-group>
Method Description Return Type
click(String) Click the button by value void
isChecked(String) Checks if radio button contain value boolean
is() Assert action RadioButtonsAssert
Here you can find Radio Button tests

2.2.2 List

List overview

List is a container component that wraps and formats a series of line items.

List is located in the following classes:

There are two different lists in Angular: Basic list and List with sections.

See an example with HTML code describing basic list element.

List examples


  //@FindBy(css = "#basic-list mat-list-item")
  @UI("#basic-list mat-list-item") 
  public JList<Label> basicList; 

  //@FindBy(css = "#list-with-sections mat-list-item")
  @UI("#list-with-sections mat-list-item") 
  public JList<Label> listWithSection; 

  @Test
  public void basicListBasicTest() {
      listSection.basicList.is().displayed();
  }

  @Test
  public void basicListTextTest() {
      listSection.basicList.get(1).is().text("Item 1");
      listSection.basicList.get(2).is().text("Item 2");
      listSection.basicList.get(3).is().text("Item 3");
  }

  @Test
  public void listWithSectionsBasicTest() {
      listSection.listWithSection.is().displayed();
  }

  @Test
  public void listWithSectionsIconTest() {
      listSection.listWithSection.get(1).children().get(3).is().text("folder");
      listSection.listWithSection.get(2).children().get(3).is().text("folder");
      listSection.listWithSection.get(3).children().get(3).is().text("folder");
      listSection.listWithSection.get(4).children().get(3).is().text("note");
      listSection.listWithSection.get(5).children().get(3).is().text("note");
  }
<mat-list id="basic-list" role="list"> 
<mat-list-item id="basic-list-item-1" role="listitem">Item 1</mat-list-item> 
<mat-list-item id="basic-list-item-2" role="listitem">Item 2</mat-list-item> 
<mat-list-item id="basic-list-item-3" role="listitem">Item 3</mat-list-item> 
</mat-list> 

To add an icon to your list item, use the matListIcon attribute. Subheader can be added to a list by annotating a heading tag with an matSubheader attribute. To add a divider, use .

See an example with HTML code describing list with sections element.

List examples

<mat-list id="list-with-sections"> 
<div mat-subheader>Folders</div> 
<mat-list-item id="{{ 'list-with-section-items-' + folder.name.toLowerCase() }}" *ngFor="let folder of folders"> 
<mat-icon mat-list-icon>folder</mat-icon> 
<div mat-line>{{folder.name}}</div> 
<div mat-line> {{folder.updated | date}} </div> 
</mat-list-item> 
<mat-divider></mat-divider> 
<div mat-subheader>Notes</div> 
<mat-list-item id="{{ 'list-with-section-items-' + note.name.toLowerCase().replace(' ','-') }}" *ngFor="let note of notes"> 
<mat-icon mat-list-icon>note</mat-icon> 
<div mat-line>{{note.name}}</div> 
<div mat-line> {{note.updated | date}} </div> 
</mat-list-item> 
</mat-list> 
Method Description Return Type
is() Assert action UISelectAssert, JList>
is(Matcher<? super List>) Assert action meets condition UISelectAssert, JList>
assertThat(Matcher<? super List>) Assert action UISelectAssert, JList>
wait(JFunc1, Boolean>) wait with condition boolean
List java tests examples

2.2.3 Grid list

Grid list overview

Grid list is a two-dimensional list view that arranges cells into grid-based layout.

Grid list is located in the following classes:

There are two different grid lists in Angular: Basic grid list and Dynamic grid list.

See an example with HTML code describing basic grid list element.

Grid list examples


  //@FindBy(css = "#basic-grid-list mat-grid-tile")
  @UI("#basic-grid-list mat-grid-tile") 
  public JList<Label> basicGridList; 

  //@FindBy(css = "#dynamic-grid-list mat-grid-tile")
  @UI("#dynamic-grid-list mat-grid-tile") 
  public JList<Label> dynamicGridList; 

  @Test
  public void basicGridListBasicTest() {
      gridListSection.basicGridList.is().displayed();
  }

  @Test
  public void basicGridListTextTest() {
      gridListSection.basicGridList.get(1).is().text("1");
  }

  @Test
  public void basicGridListColorTest() {
      gridListSection.basicGridList.get(1)
               .has().css("background-color", "rgba(" + 173 + ", " + 216 + ", " + 230 + ", 1)");
  }

  @Test
  public void dynamicGridListBasicTest() {
      gridListSection.dynamicGridList.is().displayed();
  }

  @Test
  public void dynamicGridListTextTest() {
      gridListSection.dynamicGridList.get(1).is().text("One");
  }

  @Test
  public void dynamicGridListColorTest() {
      gridListSection.dynamicGridList.get(1)
           .has().css("background-color", "rgba(" + 173 + ", " + 216 + ", " + 230 + ", 1)");
      gridListSection.dynamicGridList.get(2)
           .has().css("background-color", "rgba(" + 144 + ", " + 238 + ", " + 144 + ", 1)");
      gridListSection.dynamicGridList.get(3)
           .has().css("background-color", "rgba(" + 255 + ", " + 182 + ", " + 193 + ", 1)");
      gridListSection.dynamicGridList.get(4)
               .has().css("background-color", "rgba(" + 221 + ", " + 189 + ", " + 241 + ", 1)");
  }

See an example with HTML code describing dynamic grid list element.

Grid list examples

<mat-grid-list

id="basic-grid-list" cols="2" rowHeight="2:1"> 
<mat-grid-tile id="basic-grid-list-tile-1">1</mat-grid-tile> 
<mat-grid-tile id="basic-grid-list-tile-2">2</mat-grid-tile> 
<mat-grid-tile id="basic-grid-list-tile-3">3</mat-grid-tile> 
<mat-grid-tile id="basic-grid-list-tile-4">4</mat-grid-tile> 
</mat-grid-list> 

See an example with HTML code describing dynamic grid list element.

Grid list examples

<mat-grid-list id="dynamic-grid-list" cols="4" rowHeight="100px"> 
<mat-grid-tile 
id="{{ 'dynamic-grid-list-' + tile.text.toLowerCase() }}" 
*ngFor="let tile of tiles" 
[colspan]="tile.cols" 
[rowspan]="tile.rows" 
[style.background]="tile.color"> 
{{tile.text}} 
</mat-grid-tile> 
</mat-grid-list> 
Method Description Return Type
is() Assert action UISelectAssert, JList>
is(Matcher<? super List>) Assert action meets condition UISelectAssert, JList>
assertThat(Matcher<? super List>) Assert action UISelectAssert, JList>
wait(JFunc1, Boolean>) wait with condition boolean
Grid list java tests examples

2.2.4 Card

Card overview

Card is a content container for text, photos, and actions in the context of a single subject

Card is located in the following classes:


    //FindBy(id = "simple-card")
    @UI("#simple-card")
    public static Card simpleCard;

    //FindBy(id = "example-card")
    @UI("#example-card")
    public static Card card;

    @Test
    public void displayedBasicCardTest() {
        simpleCard.is().displayed();
        card.is().displayed();
    }

    @Test
    public void attributeCardTest() {
        simpleCard.is().assertCardText("Simple card");
        card.is().assertAltImageAttribute("Photo of a Shiba Inu");
        card.is().assertSrcImageAttribute("https://material.angular.io/assets/img/examples/shiba2.jpg");
    }

    @Test
    public void displayedCardTest() {
        card.getHeader().is().displayed();
        card.getHeaderText().is().displayed();
        card.getAvatar().is().displayed();
        card.getTitle().is().displayed();
        card.getTitle().is().text("Shiba Inu");
        card.getSubtitle().is().displayed();
        card.getSubtitle().is().text("Dog Breed");
        card.getImage().is().displayed();
        card.getContent().is().displayed();
        card.getContent().is().displayed();
    }

Card

<mat-card id="simple-card" class="mat-card mat-focus-indicator">Simple card</mat-card>
Method Description Return Type
getHeader() Get header UIElement
getAvatar() Get avatar UIElement
getHeaderText() Get header text UIElement
getTitle() Get title UIElement
getSubtitle() Get subtitle UIElement
getImage() Get image UIElement
getContent() Get content UIElement
getButtons() Get buttons UIElement
getCardText() Get card text UIElement
getButtonByText(String) Get button by text UIElement
getButtonByNumber(int) Get button by number UIElement
is() Assert action CardAssert
Card java tests examples

2.2.5 Select

Select overview

Selectors are located in the following classes:

There are two similar select elements in Angular: material and native element.

<mat-form-field> is a component used to wrap several Angular Material components and apply common Text field styles such as the underline, floating label, and hint messages.

Angular Material also supports use of the native <select> element inside of <mat-form-field>. The native control has several performance, accessibility, and usability advantages.

  //@FindBy(css = "#basic-mat-select")
  @UI("#basic-mat-select")
  public static MaterialSelector basicMatSelect;

  @Test
  public void checkLabelValue() {
      basicMatSelect.label().has().value("Favorite food");
  }

  @Test
  public void checkSelectorExpanded() {
      basicMatSelect.expand();
      basicMatSelect.is().expanded();
      basicMatSelect.collapse();
      basicMatSelect.is().collapsed();
  }

  @Test
  public void checkSelectorCollapsed() {
      basicMatSelect.collapse();
      basicMatSelect.is().collapsed();
  }

  //@FindBy(css = "#basic-native-select")
  @UI("#basic-native-select")
  public static NativeSelector basicNativeSelect;

  @Test
  public void checkPreselectedValue() {
      basicNativeSelect.verify().selected(matchesPattern("[a-zA-Z]+"));
  }

  @Test
  public void checkOptionCanBeSelectedByName() {
      basicNativeSelect.select(SAAB);
      basicNativeSelect.is().selected(SAAB);
  }

  @Test
  public void checkListDisabledOptions() {
      basicNativeSelect.has().listDisabled(Collections.EMPTY_LIST);
  }

See examples with HTML code describing select elements.

Basic Select

<mat-form-field _ngcontent-nsg-c244="" class="mat-form-field ng-tns-c95-6 mat-primary mat-form-field-type-mat-select mat-form-field-appearance-fill mat-form-field-can-float mat-form-field-has-label mat-form-field-hide-placeholder">
    <div class="mat-form-field-wrapper ng-tns-c95-6">
        <div class="mat-form-field-flex ng-tns-c95-6">
            <div class="mat-form-field-infix ng-tns-c95-6">
                <mat-select _ngcontent-nsg-c244="" role="listbox" id="basic-mat-select" class="mat-select ng-tns-c171-7 ng-tns-c95-6 ng-star-inserted mat-select-empty" tabindex="0" aria-labelledby="mat-form-field-label-13" aria-required="false" aria-disabled="false" aria-invalid="false" aria-multiselectable="false">
                    <div cdk-overlay-origin="" aria-hidden="true" class="mat-select-trigger ng-tns-c171-7">
                        <div class="mat-select-value ng-tns-c171-7">
                            <span class="mat-select-placeholder ng-tns-c171-7 ng-star-inserted">&nbsp;</span>
                        </div>
                        <div class="mat-select-arrow-wrapper ng-tns-c171-7">
                            <div class="mat-select-arrow ng-tns-c171-7"/>
                        </div>
                    </div>
                </mat-select>
                <span class="mat-form-field-label-wrapper ng-tns-c95-6">
                    <label class="mat-form-field-label ng-tns-c95-6 mat-empty mat-form-field-empty ng-star-inserted" id="mat-form-field-label-13" for="basic-mat-select" aria-owns="basic-mat-select">
                        <mat-label _ngcontent-nsg-c244="" class="ng-tns-c95-6 ng-star-inserted">Favorite food</mat-label>
                    </label>
                </span>
            </div>
        </div>
        <div class="mat-form-field-underline ng-tns-c95-6 ng-star-inserted">
            <span class="mat-form-field-ripple ng-tns-c95-6"/>
        </div>
        <div class="mat-form-field-subscript-wrapper ng-tns-c95-6">
            <div class="mat-form-field-hint-wrapper ng-tns-c95-6 ng-trigger ng-trigger-transitionMessages ng-star-inserted" style="opacity: 1; transform: translateY(0%);">
                <div class="mat-form-field-hint-spacer ng-tns-c95-6"/>
            </div>
        </div>
    </div>
</mat-form-field>

<mat-form-field _ngcontent-nsg-c244="" class="mat-form-field ng-tns-c95-8 mat-primary mat-form-field-type-mat-native-select mat-form-field-appearance-fill mat-form-field-can-float mat-form-field-should-float mat-form-field-has-label">
    <div class="mat-form-field-wrapper ng-tns-c95-8">
        <div class="mat-form-field-flex ng-tns-c95-8">
            <div class="mat-form-field-infix ng-tns-c95-8">
                <select _ngcontent-nsg-c244="" matnativecontrol="" required="" id="basic-native-select" class="mat-input-element mat-form-field-autofill-control ng-tns-c95-8 cdk-text-field-autofill-monitored" aria-invalid="false" aria-required="true">
                    <option _ngcontent-nsg-c244="" value="volvo">Volvo</option>
                    <option _ngcontent-nsg-c244="" value="saab">Saab</option>
                    <option _ngcontent-nsg-c244="" value="mercedes">Mercedes</option>
                    <option _ngcontent-nsg-c244="" value="audi">Audi</option>
                </select>
                <span class="mat-form-field-label-wrapper ng-tns-c95-8">
                    <label class="mat-form-field-label ng-tns-c95-8 ng-star-inserted" id="mat-form-field-label-15" for="basic-native-select" aria-owns="basic-native-select">
                        <mat-label _ngcontent-nsg-c244="" class="ng-tns-c95-8 ng-star-inserted">Cars</mat-label>
                        <span aria-hidden="true" class="mat-placeholder-required mat-form-field-required-marker ng-tns-c95-8 ng-star-inserted"> *</span>
                    </label>
                </span>
            </div>
        </div>
        <div class="mat-form-field-underline ng-tns-c95-8 ng-star-inserted">
            <span class="mat-form-field-ripple ng-tns-c95-8"/>
        </div>
        <div class=