ListUsersPage usersPage = basicPage.listUsers(); Assert.assertTrue ( usersPage // "List users" page .table() // The table containing the list of users .search() // The "search" component of the table .byName() // The "popover" component visible after clicking the "name" input box .inputValue(TEST_USER_TITIAN_NAME) // The "popover" component .updateSearch() // The "search" component of the table .and() // The table containing the list of users .clickByName("titian") // The page of the user .isActivationState("Enabled") );
Writing Tests With Schrödinger
|This page may be outdated.|
Here you can find some bits and pieces which could help you with writing your own tests using the Schrödinger testing framework. Additionally, we will gradually expand this page with some additional useful examples, tips and tricks. If you are looking for some information on the initial set up for execution of the test please visit this page.
Each test class which is written extends the public abstract class AbstractSchrodingerTest, this contains some of the basic annotated methods, the ones which are of use at the moment are under the @BeforeClass and @AfterClass annotations.
The @BeforeClass annotated method checks if there is already a valid base configuration present, if not it initializes the Schrodinger Midpoint class with a set of base properties containing the reference of which type of Selenide web driver is being used (At the moment only the Chrome drive is tested and supported) and additionally the schrodinger.properties property file is loaded up and some additional test deployment specific data is fetched.
The @AfterClass should clean up the environment after a suite has executed. The method should execute the Reset to factory default action and thus revert the environment to the initial state.
The AbstractSchrodingerTest also contains some common methods useful for many test implementations. These are the following:
importObject() : imports an object specified by the path
addObjectFromFile() : adds the object specified by the path programmatically, avoiding GUI import page
fetchMidpointHome(): returns a string representing the path to the midpoint home directory
refreshResourceSchema(): the schema refresh action for a specified resource is executed
initTestDirectory(): used in case there are additional files needed to be created for a test execution in a new directory dedicated for the test (i.e. creation of a resource .csv file)
Writing the actual tests
The instantiation of a class representing a GUI page is mostly done by calling the basicPage variable provided by the TestBase class which holds methods acting as accessors for most of the GUI pages. The method call returns an instance of the representative class for a specific page. The page classes each contain methods representing actions which can be executed on the components present on a specific page. Invoking a page method which returns an instance of a component will present you with the methods representing the capabilities of such component.
The tests are written in a Fluent like way this means that the original idea is to use Method chaining quite extensively. The main content of a test method should directly describe/represent each step which is done manually in the GUI.
To promote the readability of a large chain of invoked methods some rules of indentation are used. For now what proved to be the most useful method is to add a new line after each call of a method in the method chain and indent the calls in a way that each invocation of the same component on a page should be situated under each other. (e.g. see example above: Example: Method chaining)
Sometimes we want to return back from a component of a page to the actual page from which the component was invoked or some parent component from which is was invoked. For this we use the and() method which returns the instance of the parent.
Example test suite
Some tips while test writing
It happens that one page contains more than one element with the same id and the same other attributes. For example, multi value container prism form contains the same properties for each container value. As a result, selenide wrongly finds the first element with the specified parameters on the page, even if you try to look the element on the second container value panel. To solve this, use getParentElement().$x() method, for now it shows the correct behavior while getting the element from the list of similar or equal by tag/attributes elements.
It’s preferable to use addObjectFromFile() instead of importObject() method to avoid redundant usage of Import page and occasional failures.