Mastering Virtual Microscope Technology: A Comprehensive Guide

virtual microscope technology

Virtual microscope technology, also known as digital or virtual pathology, involves the digitization of optically scanned histology slides and their viewing via specialized computer software at a resolution similar to conventional microscopy. This technology has several measurable and quantifiable aspects that can be discussed in terms of resolution, image quality, storage capacity, and processing speed. … Read more

Sonar Technology: A Comprehensive Guide for Physics Students

sonar technology

Sonar technology, or Sound Navigation and Ranging, is a powerful tool used to detect and locate objects underwater by transmitting and receiving sound waves. This technology has a wide range of applications, from marine research and military surveillance to underwater construction and exploration. Understanding the Fundamentals of Sonar Technology Sonar technology relies on the propagation … Read more

Microscope in Nanotechnology: A Comprehensive Guide

microscope in nanotechnology

Microscopy in nanotechnology involves various advanced techniques, such as scanning probe microscopy (SPM) and hybrid nano-microscopy, that provide high spatial resolution and simple metrological traceability for measuring and visualizing materials at the nanoscale. These techniques are essential for researching the properties of nano-composite materials and are suitable for commercialization. Scanning Probe Microscopy (SPM) in Nanotechnology … Read more

Laser Technology: Diverse Applications Beyond Simple Pointers

where is laser technology used beyond simple pointers exploring its diverse applications

Laser technology has evolved far beyond its initial use as simple pointers, finding applications in a wide range of industries and scientific fields. From high-speed communication and precise industrial manufacturing to groundbreaking medical procedures and advanced scientific research, lasers have become indispensable tools that enable remarkable feats. This comprehensive guide delves into the diverse and … Read more

Why is Fiber Optic Technology Revolutionary: Unleashing the Power of Light

why is fiber optic technology revolutionary unleashing the power of light

Fiber optic technology has revolutionized the way we transmit and process data, enabling lightning-fast communication and powering industries across the globe. By harnessing the power of light, fiber optics have overcome the limitations of traditional copper cables, offering unprecedented bandwidth, speed, and reliability. This comprehensive guide delves into the technical details and groundbreaking advancements that … Read more

How to write Appium testing code-your complete guide 2023-24

App package 1 1024x535 1

Appium is an open-source automation tool that allows you to write scripts to test mobile applications on different platforms such as Android and iOS. With Appium, you can automate the testing process, ensuring that your mobile app functions as intended across various devices and operating systems.

Overview of Appium Testing

Appium testing is a popular choice among developers and testers due to its flexibility and ease of use. It supports multiple programming languages, including Java, Python, Ruby, and C#, making it accessible to a wide range of developers.

Appium works by interacting with the application under test, just like a real user would. It uses the WebDriver protocol to communicate with the mobile device or emulator, allowing you to perform actions such as tapping buttons, entering text, and swiping gestures.

One of the key advantages of Appium is its cross-platform support. It allows you to write a single test script that can be executed on both Android and iOS devices, saving time and effort. This cross-platform capability makes Appium a valuable tool for organizations that develop mobile applications for multiple platforms.

Supported Platforms (Android and iOS)

Appium supports both Android and iOS platforms, making it a versatile choice for mobile app testing.

Android Testing

When it comes to testing Android applications with Appium, you can write your test scripts using any programming language that Appium supports. You can use popular frameworks such as JUnit or TestNG to structure your tests and make assertions about the behavior of your app.

To automate Android testing, you need to set up the necessary tools and dependencies. This includes installing the Android SDK, setting up the Android Virtual Device (AVD) emulator, and configuring the Appium server.

Once the setup is complete, you can start writing your test scripts. Appium provides a wide range of APIs and methods that allow you to interact with the Android application under test. You can perform actions like tapping buttons, entering text, verifying text content, and validating UI elements.

iOS Testing

Appium also supports testing iOS applications, allowing you to write test scripts using the same programming languages and frameworks as Android testing.

To automate iOS testing, you need to set up the necessary tools and dependencies. This includes installing Xcode, which includes the necessary iOS simulator for testing. You also need to configure the Appium server and set up the desired capabilities for your iOS device.

Once the setup is complete, you can start writing your test scripts. Appium provides APIs and methods specifically designed for iOS testing. You can interact with UI elements, perform gestures, validate text content, and navigate through different screens of your iOS application.

How to Find App Package and Activity in Android

App package 1

To write effective scripts in Appium testing, it is crucial to identify the app package and activity of the Android application you want to automate. The app package represents the unique identifier of the application, while the activity refers to the specific screen or functionality within the app. In this section, we will explore the steps to find the app package and activity in Android, along with the commands for both Windows and Mac/Linux platforms.

Steps to Find App Package and Activity

  1. Enable Developer Options: Before proceeding, ensure that the Developer Options are enabled on your Android device. To do this, go to the device settings, scroll down to the “About phone” section, and tap on the “Build number” multiple times until you see a message indicating that you are now a developer.
  2. Access Developer Options: Once you have enabled the Developer Options, go back to the main settings menu and look for the newly unlocked “Developer options” entry. Tap on it to access the developer settings.
  3. Enable USB Debugging: Within the Developer Options, locate the “USB debugging” option and enable it. This will allow your computer to communicate with the Android device over a USB connection.
  4. Connect Android Device to Computer: Connect your Android device to your computer using a USB cable. Make sure to authorize the computer‘s RSA key fingerprint on your device if prompted.
  5. Open Command Prompt or Terminal: On Windows, open the Command Prompt by pressing the Windows key + R, typing “cmd,” and hitting Enter. On Mac/Linux, open the Terminal by searching for it in the applications or using the keyboard shortcut Command + Space and typing “Terminal.”
  6. Navigate to Android SDK Tools: In the Command Prompt or Terminal, navigate to the directory where you have installed the Android SDK tools. This is typically located in the “platform-tools” folder within the Android SDK installation directory.
  7. Execute ADB Commands: Once you are in the Android SDK tools directory, execute the following command to list all the connected devices:

adb devices

This will display the device ID of your connected Android device.

  1. Find App Package and Activity: To find the app package and activity, execute the following command:

adb shell dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp'

This command will provide you with the current app package and activity details.

Commands for Windows and Mac/Linux

Here are the commands for finding the app package and activity in Android using Appium on both Windows and Mac/Linux platforms:

Windows:

  1. Enable Developer Options on your Android device.
  2. Connect your Android device to your computer via USB.
  3. Open the Command Prompt by pressing the Windows key + R, typing “cmd,” and hitting Enter.
  4. Navigate to the Android SDK tools directory using the cd command.
  5. Execute the command adb devices to list the connected devices.
  6. Execute the command adb shell dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp' to find the app package and activity.

Mac/Linux:

  1. Enable Developer Options on your Android device.
  2. Connect your Android device to your computer via USB.
  3. Open the Terminal by searching for it in the applications or using the keyboard shortcut Command + Space and typing “Terminal.”
  4. Navigate to the Android SDK tools directory using the cd command.
  5. Execute the command ./adb devices to list the connected devices.
  6. Execute the command ./adb shell dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp' to find the app package and activity.

By following these steps and executing the appropriate commands, you can easily find the app package and activity of an Android application. This information is essential for writing effective scripts in Appium testing, as it allows you to interact with specific screens and functionalities within the app.

How to Create a Maven Project for Appium Testing

Untitled design3

Appium is an open-source automation tool used for testing mobile applications. It allows you to write scripts in various programming languages to automate the testing process. In this section, we will discuss how to create a Maven project for Appium testing, which will help you manage dependencies and build your project more efficiently.

Prerequisites for Creating a Maven Project

Before we dive into creating a Maven project for Appium testing, let’s ensure we have the necessary prerequisites in place. Here are a few things you’ll need:

  1. Java Development Kit (JDK): Make sure you have the latest version of JDK installed on your system. Maven requires JDK to compile and run your code.
  2. Maven: Install Maven on your machine. You can download the latest version of Maven from the official Apache Maven website.
  3. Integrated Development Environment (IDE): Choose an IDE of your preference. Popular choices include Eclipse, IntelliJ IDEA, and Visual Studio Code. Install the necessary plugins for Maven integration.
  4. Appium Server: Download and install the Appium server on your machine. Appium server acts as a bridge between your test scripts and the mobile device or emulator.

Steps to Create a Maven Project

Now that we have the prerequisites sorted, let’s move on to creating a Maven project for Appium testing. Follow these steps:

  1. Open your IDE: Launch your preferred IDE and create a new Maven project. Choose the appropriate Maven archetype for your project. For Appium testing, the “maven-archetype-quickstart” archetype is commonly used.
  2. Configure project details: Provide the necessary details such as Group Id and Artifact Id for your project. These details will be used to identify your project within the Maven ecosystem.
  3. Project structure: Once the project is created, you will see a predefined project structure. The main source code files will be located under the “src/main/java” directory.
  4. Create a test class: Inside the “src/main/java” directory, create a new package for your test scripts. Create a new Java class within this package to write your Appium test scripts.
  5. Configure dependencies: We will now add the necessary dependencies to the project’s pom.xml file. This file is located in the root directory of your project. Open the pom.xml file and add the required dependencies for Appium testing.

Adding Dependencies to the pom.xml File

To successfully run Appium tests, we need to add the required dependencies to the pom.xml file. These dependencies will be downloaded by Maven and included in your project’s classpath. Here are a few commonly used dependencies for Appium testing:

Dependency Description
io.appium Contains the core classes and methods for interacting with the Appium server.
org.testng Provides the TestNG framework for writing and executing test cases.
org.seleniumhq.selenium Includes the Selenium WebDriver, which is used for automating browser interactions.
org.apache.commons Offers utility classes and methods that can be helpful in your test scripts.

To add these dependencies, open the pom.xml file and locate the <dependencies> section. Add the necessary dependencies within the <dependencies> tags. Here’s an example:

xml
<dependencies>
<dependency>
<groupId>io.appium</groupId>
<artifactId>java-client</artifactId>
<version>7.5.1</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.4.0</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
</dependencies>

Once you have added the dependencies, save the pom.xml file. Maven will automatically download the required dependencies and make them available in your project.

Congratulations! You have successfully created a Maven project for Appium testing and added the necessary dependencies. Now you can start writing your Appium test scripts and execute them using Maven.

In the next section, we will explore how to write effective test scripts in Appium and discuss best practices for script development. Stay tuned!

Desired Capabilities in Appium Testing

Untitled design8

In Appium testing, desired capabilities play a crucial role in configuring and customizing the test automation process. Desired capabilities are a set of key-value pairs that define the characteristics of the test environment, such as the platform, device, and application settings. By specifying these capabilities, testers can ensure that their Appium scripts run on the desired target device or emulator.

When writing scripts in Appium, it is essential to understand how to set the desired capabilities correctly. Let’s explore the desired capabilities for Android and iPhone devices.

Desired Capabilities for Android

When testing Android applications with Appium, there are several desired capabilities that you can set to configure the test environment. Here are some commonly used desired capabilities for Android:

  1. platformName: Specifies the platform on which the test will run, such as “Android” or “iOS.”
  2. deviceName: Specifies the name of the Android device or emulator on which the test will execute.
  3. app: Specifies the path to the APK file or the package name of the application under test.
  4. automationName: Specifies the automation engine to be used, such as “UiAutomator2” or “Espresso.”
  5. appPackage and appActivity: Specifies the package name and activity name of the application under test, respectively.
  6. udid: Specifies the unique device identifier (UDID) of the Android device.

By setting these desired capabilities, you can configure the test environment to match your specific requirements for Android testing.

Desired Capabilities for iPhone

Untitled design9

Similar to Android, when testing iPhone applications with Appium, you can set desired capabilities to customize the test environment. Here are some commonly used desired capabilities for iPhone:

  1. platformName: Specifies the platform on which the test will run, such as “Android” or “iOS.”
  2. deviceName: Specifies the name of the iPhone device or simulator on which the test will execute.
  3. app: Specifies the path to the .app file or the bundle identifier of the application under test.
  4. automationName: Specifies the automation engine to be used, such as “XCUITest” or “UIAutomation.”
  5. bundleId: Specifies the bundle identifier of the application under test.
  6. udid: Specifies the unique device identifier (UDID) of the iPhone device.

By setting these desired capabilities, you can configure the test environment to match your specific requirements for iPhone testing.

How to Write an Appium Testing Script for Android

App package1

Appium is an open-source automation tool that enables you to write and execute tests for mobile applications. It supports both Android and iOS platforms, making it a popular choice among developers and testers. In this section, we will discuss the steps involved in writing an Appium testing script for Android and provide a sample code for reference.

Steps to Write an Appium Testing Script

Writing an Appium testing script requires a systematic approach to ensure accurate and efficient test execution. Here are the steps you can follow to write an Appium testing script for Android:

  1. Set up the development environment: Before you begin writing the script, you need to set up the development environment. This includes installing the necessary software, such as Java Development Kit (JDK), Android SDK, and Appium server. Make sure to configure the environment variables properly.
  2. Identify the test scenarios: Determine the test scenarios you want to cover in your script. This involves understanding the functionality of the application and identifying the key features that need to be tested. It is important to have a clear understanding of the expected behavior of the application under different conditions.
  3. Inspect the application: Use the Appium Inspector tool to inspect the elements of the application. This tool allows you to identify the unique identifiers (such as resource-id, class name, or xpath) for the elements you want to interact with during the test. Inspecting the application helps you in locating the elements accurately in your script.
  4. Write the test script: Once you have identified the test scenarios and inspected the application, you can start writing the test script. The script should be written in a programming language that is supported by Appium, such as Java, Python, or JavaScript. You can use any Integrated Development Environment (IDE) of your choice to write the script.
  5. Configure the desired capabilities: Before executing the test script, you need to configure the desired capabilities. Desired capabilities are a set of key-value pairs that define the characteristics of the test environment, such as the device name, platform name, and application package name. These capabilities help Appium in establishing a connection with the device and launching the application.
  6. Implement test actions: In the test script, you need to implement the test actions that simulate user interactions with the application. These actions can include tapping on elements, entering text, swiping, scrolling, or any other action that you want to perform during the test. You can use the element locators identified during the inspection phase to interact with the elements.
  7. Add assertions: Assertions are used to verify the expected behavior of the application. You can add assertions in your test script to check if the application is behaving as expected. For example, you can assert that a certain element is present on the screen, or the text entered in a text field is displayed correctly.
  8. Execute the test script: Once you have written the test script, you can execute it using the Appium server. Make sure to connect the device or emulator to the computer and start the Appium server before executing the script. The server will establish a connection with the device and execute the test script, providing you with the test results.

Sample Code for Reference

Here is a sample code snippet in Java that demonstrates how to write an Appium testing script for Android:

“`java
import
io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.net.URL;

public class AppiumTestScript {
public static void main(String[] args) throws Exception {
// Set the desired capabilities
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability(“deviceName”, “Android Device”);
caps.setCapability(“platformName”, “Android”);
caps.setCapability(“appPackage”, “com.example.app”);
caps.setCapability(“appActivity”, “com.example.app.MainActivity”);

    // Create a new instance of the AndroidDriver
    AndroidDriver<AndroidElement> driver = new AndroidDriver<>(new URL("http://localhost:4723/wd/hub"), caps);

    // Perform test actions
    // ...

    // Add assertions
    // ...

    // Close the driver
    driver.quit();
}

}
“`

This code sets the desired capabilities, creates an instance of the AndroidDriver, performs test actions, adds assertions, and finally closes the driver. You can customize the code according to your test scenarios and application.

Writing an Appium testing script for Android requires a combination of technical skills and understanding of the application under test. By following the steps mentioned above and referring to the sample code, you can create effective and reliable test scripts for your Android applications using Appium.

How to Write an Appium Testing Script for iPhone

Appium is an open-source automation tool that allows you to automate mobile app testing across different platforms, including iOS. In this section, we will explore the steps to write an Appium testing script for iPhone and provide a sample code for reference.

Steps to Write an Appium Testing Script

Writing an Appium testing script for iPhone involves several steps. Let’s walk through them one by one:

  1. Set up the environment: Before you start writing the script, ensure that you have the necessary tools installed. This includes Appium, Xcode, and the iOS Simulator. You can install these tools by following the official documentation provided by Appium and Apple.
  2. Create a new project: Once your environment is set up, create a new project in your preferred programming language. Appium supports multiple programming languages, such as Java, Python, and JavaScript. Choose the language you are comfortable with and create a new project.
  3. Import the necessary libraries: In your project, import the necessary libraries or dependencies required for Appium. These libraries provide the functions and methods needed to interact with the Appium server and control the iOS Simulator.
  4. Set desired capabilities: Before launching the Appium server, set the desired capabilities for your iPhone device. These capabilities include the device name, platform version, and app package name. You can find the desired capabilities specific to your device in the Appium documentation.
  5. Start the Appium server: Launch the Appium server using the desired capabilities you set in the previous step. The Appium server acts as a bridge between your script and the iOS Simulator, allowing you to interact with the app.
  6. Write test cases: Now it’s time to write the actual test cases in your script. Test cases are a set of instructions that simulate user interactions with the app. For example, you can write test cases to tap on a button, enter text in a text field, or verify the presence of an element on the screen.
  7. Execute the script: Once you have written the test cases, execute the script. The script will communicate with the Appium server, which in turn interacts with the iOS Simulator and performs the actions specified in the test cases.

Sample Code for Reference

Here’s a sample code snippet in Java that demonstrates how to write an Appium testing script for iPhone:

“`java
import
io.appium.java_client.MobileElement;
import io.appium.java_client.ios.IOSDriver;
import org.openqa.selenium.remote.DesiredCapabilities;

public class AppiumTest {
public static void main(String[] args) {
// Set desired capabilities
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability(“platformName”, “iOS”);
caps.setCapability(“platformVersion”, “14.5”);
caps.setCapability(“deviceName”, “iPhone 12”);
caps.setCapability(“app”, “path/to/your/app”);

    // Create driver instance
    IOSDriver<MobileElement> driver = new IOSDriver<>("http://localhost:4723/wd/hub", caps);

    // Write test cases
    // ...

    // Execute the script
    // ...

    // Quit the driver
    driver.quit();
}

}
“`

In this code snippet, we import the necessary libraries, set the desired capabilities for the iPhone device, create an instance of the driver, write test cases, execute the script, and finally quit the driver.

Feel free to modify and customize this sample code according to your specific testing requirements.

By following these steps and referring to the sample code, you can start writing your own Appium testing script for iPhone. Remember to explore the Appium documentation and experiment with different test cases to ensure comprehensive test coverage for your mobile app.

TestNG Assert in Appium Testing

Explanation of TestNG Assert

When it comes to appium testing, one of the essential aspects is the ability to verify whether the expected behavior of the application is met. This is where TestNG Assert comes into play. TestNG is a testing framework that provides a set of assertion methods to validate the expected outcomes of your test cases.

TestNG Assert allows you to check if a particular condition is true and throws an exception if it is not. It helps in ensuring that the app is functioning as expected and helps identify any discrepancies or bugs in the application.

Usage of TestNG Assert in the code

To understand the usage of TestNG Assert in appium testing, let’s consider an example scenario. Suppose we have an app that has a login functionality, and we want to verify if the login is successful.

Here’s how you can use TestNG Assert in your appium test script:

  1. Import the necessary TestNG and appium libraries:

java
import org.testng.Assert;
import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;

  1. Set up the desired capabilities and initialize the appium driver:

“`java
DesiredCapabilities
caps = new DesiredCapabilities();
caps.setCapability(“deviceName”, “Your_Device_Name”);
caps.setCapability(“platformName”, “Android”);
caps.setCapability(“appPackage”, “com.example.app”);
caps.setCapability(“appActivity”, “com.example.app.MainActivity”);

AndroidDriver driver = new AndroidDriver(new URL(“http://127.0.0.1:4723/wd/hub”), caps);
“`

  1. Write the test case to verify the login functionality:

“`java
@Test
public void testLogin
() {
// Perform actions to navigate to the login screen

// Enter valid credentials
driver.findElement(By.id("username")).sendKeys("testuser");
driver.findElement(By.id("password")).sendKeys("password");

// Click on the login button
driver.findElement(By.id("loginButton")).click();

// Verify if the login is successful
Assert.assertTrue(driver.findElement(By.id("welcomeMessage")).isDisplayed(), "Login failed!");

}
“`

In the above code snippet, we first navigate to the login screen and enter valid credentials. Then, we click on the login button. Finally, we use TestNG Assert to check if the welcome message is displayed after a successful login. If the welcome message is not displayed, the assertion will fail, and the specified error message “Login failed!” will be shown.

By using TestNG Assert, you can easily validate various aspects of your app‘s functionality, such as checking if elements are present, verifying text values, or validating expected behaviors.

Summary

References

Here are some valuable resources that can help you in writing scripts for Appium testing:

  1. Maven documentation: Maven is a popular build automation tool used in Java projects. It simplifies the process of managing dependencies and building projects. The Maven documentation provides detailed information on how to set up Maven for your Appium testing project, including the necessary configurations and dependencies. It also offers guidance on how to structure your project and manage its lifecycle. You can find the official Maven documentation here.
  2. TestNG documentation: TestNG is a testing framework that can be integrated with Appium to create robust and scalable test scripts. It provides advanced features such as parallel test execution, data-driven testing, and test configuration through XML files. The TestNG documentation offers comprehensive guidance on how to write test scripts using TestNG annotations, assertions, and other features. It also covers topics like test configuration, test suites, and reporting. You can access the official TestNG documentation here.

By referring to these resources, you can enhance your understanding of Appium testing and improve your script writing skills. These documentation sources provide step-by-step instructions, code examples, and best practices to help you write efficient and maintainable test scripts.

Additionally, you can explore online forums, blogs, and tutorials dedicated to Appium testing. These platforms often provide practical examples, tips, and tricks shared by experienced professionals in the field. Engaging with the Appium testing community can further expand your knowledge and help you stay up-to-date with the latest developments in the field.

Remember, writing effective scripts requires a combination of technical knowledge, understanding of the application under test, and a systematic approach. By leveraging the resources mentioned above and continuously practicing and refining your skills, you can become proficient in writing scripts for Appium testing.

Frequently Asked Questions

How to write appium tests?

To write appium tests, you need to follow these steps:
1. Set up the necessary environment for appium.
2. Write the test script using the appium scripting language.
3. Use the appropriate appium commands to interact with the mobile application.
4. Run the test script and analyze the results.

How to write a test script for software testing?

To write a test script for software testing, you can follow these guidelines:
1. Identify the test scenario and the expected outcome.
2. Define the necessary test data and test environment.
3. Write the test steps in a clear and concise manner.
4. Include assertions to validate the expected results.
5. Consider error handling and exception scenarios.
6. Execute the test script and analyze the test results.

How to run appium scripts in Jenkins?

To run appium scripts in Jenkins, you can follow these steps:
1. Install the necessary plugins for appium integration in Jenkins.
2. Set up the Jenkins job to execute the appium script.
3. Configure the job to use the appropriate appium server and device configurations.
4. Schedule the job to run at the desired frequency or trigger it manually.
5. Monitor the Jenkins console output for the test execution results.

How to write automated test scripts?

To write automated test scripts, you can follow these steps:
1. Identify the test scenarios that can be automated.
2. Choose an appropriate automation framework or tool.
3. Set up the necessary environment for test automation.
4. Write the test scripts using the chosen automation tool or programming language.
5. Include assertions and validations to verify the expected results.
6. Execute the automated test scripts and analyze the test results.

How to write appium code in Eclipse?

To write appium code in Eclipse, you can follow these steps:
1. Install the necessary plugins for appium integration in Eclipse.
2. Set up the project and configure the build path.
3. Create a new class or package to hold the appium code.
4. Write the appium script using the appium scripting language.
5. Use the appropriate appium commands to interact with the mobile application.
6. Run the appium script from Eclipse and analyze the results.

What is a test script in software testing with example?

A test script in software testing is a set of instructions or commands that define the steps to be executed to validate the functionality of a software application. It typically includes the input data, the expected output, and any assertions or validations to be performed.

For example, a test script for a login functionality may include steps like entering valid credentials, clicking the login button, and verifying that the user is successfully logged in.

How to write appium test script example?

To write an appium test script example, you can follow these steps:
1. Set up the necessary environment for appium.
2. Write the test script using the appium scripting language.
3. Use appium commands to interact with the mobile application.
4. Include assertions or validations to verify the expected results.
5. Run the test script and analyze the results.

What are the best practices for appium script development?

Some best practices for appium script development include:
1. Using descriptive and meaningful variable and method names.
2. Organizing the code into reusable functions or modules.
3. Implementing proper error handling and exception handling.
4. Using appropriate waits and synchronization techniques.
5. Implementing logging and reporting mechanisms.
6. Regularly reviewing and refactoring the code for better maintainability.

How to debug appium scripts?

To debug appium scripts, you can follow these steps:
1. Enable the debugging mode in your appium setup.
2. Use breakpoints or logging statements in your script to identify the issue.
3. Analyze the logs and error messages to pinpoint the problem.
4. Use the appium inspector or other debugging tools to inspect the application state during script execution.
5. Make necessary changes to the script and re-run it to verify the fix.

What are some tips for writing appium scripts?

Here are some tips for writing appium scripts:
1. Plan and design your test scenarios before writing the script.
2. Use descriptive and meaningful names for elements and variables.
3. Implement proper error handling and exception handling.
4. Use appropriate waits and synchronization techniques.
5. Include assertions or validations to verify the expected results.
6. Regularly review and refactor your script for better maintainability.

Cypress Assertion: 9 Facts You Should Know

cypress logo 2 300x157 2

Cypress Assertion helps us to assert a particular Assertions are validation steps that ensures whether the expected result is equal to the actual result. In test automation, we assert a statement to verify that the test is generating the expected result. If the assertion fails, then the test case fails ensuring that there is a bug. In this article, we will discuss about Cypress Assertion with Handson implementation and examples.

Table of Content

Cypress Assertion

What is Cypress Assertion?

Cypress uses and wraps Chai assertion library and extensions like Sinon and JQuery. Cypress automatically waits and retries until the assertion is resolved. Assertions can be used to describe how the application should look like. We can use Cypress assertions with combination of waits, retry, block until it reaches the desired state.

Cypress Assert Text

In general English, we would describe an assertion something like, I would expect the button to have login text. The same assertion can be written in Cypress as

cy.get('button').should('have.value', 'login')

The above assertion will pass if the button has ‘login’ value.

Cypress Common Assertions

There are a set of common Cypress assertion that we use in our test cases. We will be using them with .should() . Let us look into the use case and examples.

Some of the common Cypress assertion are listed below

  1. Length
  2. Value
  3. Text Context
  4. Class
  5. Existence
  6. CSS
  7. Visibility
  8. State
  9. Disabled Property

Cypress Length Assertion

length() will check if the particular element has length

cy.get('dropdown').should('have.length', 5)

Cypress Value Assertion

The Cypress value will assert if the particular element has the expected value

cy.get('textfield').should('have.value', 'first name')

Cypress Text Context Assertion

Text context will assert if the element has the particular text

cy.get('#user-name').should('have.text', 'John Doe')

Cypress Class Assertion

Asserts whether the class is present or the particular element should have the class

cy.get('form').find('input').should('have.class', 'disabled')

Cypress Existence Assertion

Existence command checks whether the particular element is present or exist in the DOM or not

cy.get('#button').should('exist')

Cypress CSS Assertion

CSS Assertion checks whether the particular elements has a particular property

cy.get('.completed').should('have.css', 'text-decoration', 'line-through')

Cypress Visibility Assertion

Cypress Visibility Assertion asserts whether the DOM element is visible in the UI

cy.get('#form-submit').should('be.visible')

Cypress State Assertion

Asserts the state of the DOM element

cy.get(':radio').should('be.checked')

Cypress Disabled Property Assertion

Cypress Disabled property assertion asserts whether the element is disabled

cy.get('#example-input').should('be.disabled')

Cypress Retry Assertion

A single command followed with an assertion will execute in order. Initially, the command executes and then the assertion will get executed. A single command followed by multiple assertions will also execute in order – first and second assertion respectively. So when the first assertion passes, the first and the second assertion will be executed along with the commands again.

For example, the below command contains both .should() and .and() assertion commands, where .and() is otherwise known as .should()

cy.get('.todo-list li') // command
  .should('have.length', 2) // assertion
  .and(($li) => {
    // 2 more assertions
    expect($li.get(0).textContent, 'first item').to.equal('todo A')
    expect($li.get(1).textContent, 'second item').to.equal('todo B')
  })

Cypress Assertion Examples

In this section, we will discuss on the different types of assertions in Cypress such as

  • Implicit Assertion
  • Explicit Assertion

We will look into detail on both the types with examples

Implicit Assertion in Cypress

In implicit assertion, we use .should() or .and() commands. These assertion commands apply to the currently yielded subject in the chain of commands. They are dependant on the previously yielded subject.

We will look into an example on how to use .should() or .and() commands

cy.get('button').should('have.class', 'enabled')

With .and() which is an alias of .should() ,we can chain multiple assertions. These commands are more readable.

cy.get('#title')
  .should('have.class', 'active')
  .and('have.attr', 'href', '/post')

The above example is chained with .should() stating it should have the class “active”, followed by .and() is executed against the same command. This is very helpful when we want to assert multiple commands.

Explicit Assertion in Cypress

Passing explicit subject in the assertions falls under the explicit type of Cypress assertion. Here, we will use expect and assert commands as assertion. Explicit assertions are used when we want to use multiple assertions for the same subject. We also use explicit assertion in Cypress when we want to do custom logic prior making the assertion.

We will look into the example for explicit Cypress assertion

expect(true).to.be.true //checks for a boolean
expect(object).to.equal(object)

Negative Cypress Assertion

Similar to positive assertions, there are negative assertion in Cypress. We will be using “not” keyword added to the prefix of the assertion statement. Let us see an example of negative assertion

cy.get('#loading').should('not.be.visible')

Negative assertion is recommended only in cases to verify that a particular condition is no longer available after a specific action is performed by the application.

For example, let us consider that a toggle is checked and verify that it has been removed

// at first the item is marked completed
cy.contains('li.todo', 'Write tests')
  .should('have.class', 'completed')
  .find('.toggle')
  .click()
// the CSS class has been removed
cy.contains('li.todo', 'Write tests').should('not.have.class', 'completed')

Cypress Custom Assertion Message

With Cypress, we can provide additional information or custom message for assertions by using a library of matchers. Matchers comprises of small functions that differentiate values and will throw detailed error message. Chai assertion library will help our code look more readable and test failure very useful

const expect = require('chai').expect
it('checks a number', () => {
  const value = 10
  const expected = 3
  expect(value).to.equal(expected)
})
cyyy
Cypress Custom Error message

Cypress Assertion Best Practices

We can write multiple assertions in a single block by using a chain of commands. It is not necessary to write single assertion like in unit tests. Many write assertions like below. It is okay to write in that manner, but it increases the line of code and redundancy.

describe('my form', () => {
  before(() => {
    cy.visit('/users/new')
    cy.get('#first').type('ashok')
  })
  it('has validation attribute', () => {
    cy.get('#first').should('have.attr', 'data-validation', 'required') // asserting whether the #first has required field
  })
  it('has active class', () => {
    cy.get('#first').should('have.class', 'active') // asserting whether the #first has active class
  })
  it('has formatted first name', () => {
    cy.get('#first').should('have.value', 'Ashok') // asserting whether the #first has capitalized first letter
  })
})

As you see above, the same selector and assertion type is getting repeated. Instead, we can chain these commands in one single assertion which performs all the checks in a linear fashion.

describe('my form', () => {
  before(() => {
    cy.visit('/users/new')
  })
  it('validates and formats first name', () => {
    cy.get('#first')
      .type('ashok')
      .should('have.attr', 'data-validation', 'required')
      .and('have.class', 'active')
      .and('have.value', 'Ashok')
  })
})

As mentioned above, we can chain the single selector with multiple assertions! This is one of the recommended best practices of writing assertion in Cypress.

To understand about the Page Object Model in Cypress, click here.

Cypress Fixtures: 5 Important Facts You Should Know

fix 1 1024x721 1

One of the best practices in test automation is separating the test data from the test files. This aspect is one of the primary requirement while designing test framework. Cypress helps us the abilities to separate the test data with Cypress Fixtures. In this topic, we will be discussing about Cypress fixtures with hands-on implementation and real time examples

Table of Contents

What is a fixture in Cypress?

Cypress Fixtures can be used source data from external files. Fixtures in Cypress help you to read from or write into files. One of the popular framework in test automation is Data-driven framework where we separate data from the test files. We usually keep the data in external file like Excel and read them using external libraries. Cypress provides us the same feature to read data from files.

Cypress provides us a folder called fixtures, where we can create JSON files and read data from it where we can read those files in multiple test files. We will store the data as key-value pair and access them.

How to use Cypress Fixtures in Tests?

We can access Cypress fixtures via the following syntax given below

cy.fixture(filePath)
cy.fixture(filePath, encoding)
cy.fixture(filePath, options)
cy.fixture(filePath, encoding, options)

We will understand the parameters that can be passed in fixtures

filepath – the path to where you have stored your test data

encoding – The encoding that are used while using a file. Some of the encodings are ascii, base64,hex,binary etc

options – In options, we can pass the timeout response. It is to specify the timeout to resolve cy.fixture()

How to read data from Fixtures in Cypress?

We will be defining the test data in a file under the fixture folder. We will be accessing the test data from the JSON file in the test script using Cypress fixtures.

Now, let us undertand an example for Cypress fixtures. We will be logging in the url using the username and password. So let us store the username and password values in a file.

Let us create a file named credentials.json under the fixture folder. We will be defining the variables in JSON format.

{
    "username" : "[email protected]",
    "password" : "admin",
    "adminUrl" : "https://admin-demo.nopcommerce.com/admin/"
}
fix 1
Fixture file example

Accessing the values from the Fixture file to the test file

Since we have defined our JSON values in the credentials.json file, we will see how we can access them in our test file using Cypress fixtures.

We will access the fixture data using the this keyword in the before hook

describe("Cypress Fixtures Example", function () {
    before(function () {
        cy.fixture('credentials').then(function (testdata) {
            this.testdata = testdata
        })
    })
})

In the above example, we are accessing our JSON file via cy.fixture(‘credentials’). Since our JSON file name is credentials.json, we are passing the file name in cy.fixture(). Now we are using alias concept and defining our data as testdata. With the variable testdata, we can use the values of username and password in our test file

describe("Cypress Fixtures Example", function () {
    before(function () {
        cy.fixture('credentials').then(function (testdata) {
            this.testdata = testdata
        })
    })
    it("Login with valid credentials", function () {
        cy.visit(this.testdata.adminUrl)
        cy.get('[id=Email]').clear()
        cy.get('[id=Email]').type(this.testdata.username)
        cy.get('[id=Password]').clear()
        cy.get('[id=Password]').type(this.testdata.password)
        cy.get('[type=submit]').click();
        cy.url().should('be.equal', this.testdata.adminUrl)
    });
});

As you can see above, in .type() we are passing the value from our credentials.json file as this.testdata.username. Similarly, for password we are accessing the value using this.testdata.password. For the url, we are using the same way as username and password.

When we run the test case, you can see the value getting printed in the dashboard. This way, we have executed our test case using Cypress Fixtures

fix 2
Fixture test result

Cypress Multiple Fixtures

In this section, we will understand how to use Cypress Fixtures with multiple fixture files.

If we want to use different fixture data for the same test file, for example, there are two set of credentials we need to verify for the login page, how can we access the files?

One way is to write multiple it blocks which will replicate the same code again and again. The other way, we can use Cypress fixtures to access different test data in the spec file. Let us see how we can achieve that using Cypress fixtures

We already have a fixture file called credentials.json.

{
    "username" : "[email protected]",
    "password" : "admin",
    "adminUrl" : "https://admin-demo.nopcommerce.com/admin/"
}

Now let us create another fixture file named userData.json where we will use different invalid username and password.

{
    "username" : "[email protected]",
    "password" : "user",
    "adminUrl" : "https://admin-demo.nopcommerce.com/admin/"
}

Now let us see how we can access the two different data in our test file.

We will refactor the same test file using the condition of using two different fixture files.

const testValueFixtures = [
    {
        "name": "credentials",
        "context": "1"
    },
    {
        "name": "userData",
        "context": "2"
    }
]
describe('Automation Test Suite - Fixtures', function () {
    //looping through both the fixtues 
    testValueFixtures.forEach((fixtureData) => {
        describe(fixtureData.context, () => {
            // accessing the test data from the fixture file
            before(function () {
                cy.fixture(fixtureData.name).then(function (testData) {
                    this.testData = testData;
                })
            })
            it("login", function () {
                cy.visit('https://admin-demo.nopcommerce.com/admin/')
                cy.get('[id=Email]').clear()
                cy.get('[id=Email]').type(this.testData.username)
                cy.get('[id=Password]').clear()
                cy.get('[id=Password]').type(this.testData.password)
                cy.get('[type=submit]').click();
                cy.url().should('be.equal', this.testData.adminUrl)
            })
        })
    })
})
fix 3
Accessing two fixture data example

Initially, we are creating a variable called testValueFixtures as an array where we are creating the context of two fixture files. In the first context, we are passing the name as ‘credentials‘ and the second as ‘userData‘ , as they represent our JSON file names where we have our value defined.

Secondly, we are looping through the both the fixture variables in describe block. And as we discussed previously, we are accessing the data in before block using .this()

The rest of the code is the same, where we are passing the data in the cy.get()

When we execute our test, it will run in two sets where the first case passes with valid credentials and the second fails due to invalid credentials

fix 4
Fixture using the first fixture file

As you can see above in the snapshot, the first test case has passed and it has entered the value from the first fixture file credentials.json

fix 5
Fixture example using the second fixture file

As you can see in the above screenshot, the test has failed and the values passed are from the second fixture file userData.json

You can also view how to write Cypress fixtures using the Page Object Model here

Cypress Commands & Custom Commands: 21 Important Facts

anysnap 01 oct 2021 at 4 03 59 pm 300x202 1

Table of Contents

Cypress command

What is Cypress Commands?

Cypress provides us API’s and methods to interact with the UI of the application. They are known as Cypress Commands and helps with the interaction of the web application. All the commands that are available have in-built methods and we will only invoke the methods in our test cases. The Cypress commands will simulate a similar action to an user trying to perform operations on the application.

UI Interaction Commands provided by Cypress

There are different commands provided by Cypress that interact with the UI. We will look into the list of all the commands in detail.

  • .click()
  • .dblclick()
  • .rightclick()
  • .type()
  • .clear()
  • .check()
  • .uncheck()
  • .select()
  • .trigger()

Cypress Click Command

.click() – This command is to click any element on the DOM.

The following are the syntaxes for click command

.click() 

.click(options) 

.click(position) 

.click(position, options) 

.click(xCoordinate, yCoordinate) 

.click(xCoordinate, yCoordinate, options) 

As you can see above, the click accepts parameters like options, position, and coordinates.

Options

The possible options that can be passed to click are

OptionDefaultDescription
altKeyfalseSwitch on the Alternate key (Option Key in Mac), as optionKey
ctrlKeyfalseSwitch on the control key. Also known as: controlKey.
metaKeyfalseActuates the meta key (Windows key in Windows or command key in Mac). Also: commandKeycmdKey.
shiftKeyfalseActuates the shift key
logtruePrints the logs in the command line
forcefalseThis option forces the action and disables the wait for actionability
multiplefalseSequentially click multiple elements
timeoutdefaultCommandTimeoutTime for .click() wait before resolving the time out
waitForAnimationswaitForAnimationsOption to wait for the elements to complete animating before executing the command
Options in Click

Positions

The different types of positions that can be passed to .click() are

  • center (default)
  • left
  • right
  • top
  • topLeft
  • topRight
  • bottom
  • bottomLeft
  • bottomRight

Example

cy.get('btn').click()  //clicking the button 
cy.get('btn').click({ force: true })  //clicking the button by passing the option 'force' as true
cy.get('btn').click('bottomRight') // clicking the button at the botton right position
cy.get('btn').click(10, 70, { force: true }) // clicking the button with position value and force true

Cypress Double Click Command

Double click can be achieved by using dblclick() syntax in Cypress.

Syntax

.dblclick()
.dblclick(position)
.dblclick(x, y)
.dblclick(options)
.dblclick(position, options)
.dblclick(x, y, options)

Options

.dblclick() accepts all the options that are accepted by .click(). You can find the options in the above section.

Positions

All the possible positions that are specified in .click() are also available for dblclick(). The list of the positions can be found in the above section.

Example

cy.get('button').dblclick() // Double click on button
cy.focused().dblclick() // Double click on element with focus
cy.contains('Home').dblclick() // Double click on first element containing 'Home'
cy.get('button').dblclick('top') // Double click on the button on top position
cy.get('button').dblclick(30, 10) // Double click on the coordinates of 30 and 10

Cypress Right Click Command

This Cypress command, right clicks the DOM element .rightclick() command will not open context menus of the browser.rightclick() is used to test handling of right click related events in the application such as contextmenu.

Syntax

.rightclick()
.rightclick(position)
.rightclick(options)
.rightclick(position, options)
.rightclick(x, y)
.rightclick(x, y, options)

Options

As we saw above, all the options that are accepted by .click() command can be configured with .rightclick() command too.

Positions

All the possible positions that can be passed to the .rightclick() is same as the .click() mentioned above.

Example

cy.get('.welcome').rightclick() // Right click on .welcome
cy.focused().rightclick() // Right click on element with focus
cy.contains('January').rightclick() // Right click on first element containing 'January'
cy.get('button').dblclick('topRight') // Double click on the button on top right position
cy.get('button').dblclick(80, 20) // Double click on the coordinates of 80 and 20

Cypress Type Command

.type() command enters value into a DOM element.

Syntax

.type(text)
.type(text, options)

Arguments

.type() accepts string as an argument. Values passed to .type() can include any of the special character sequences given below.

SequenceNotes
{{}Enters the literal { key
{backspace}Deletes character from right to the left of the cursor
{del}Removes character from left to the right of the cursor
{downarrow}Shifts cursor down
{end}Shifts cursor to the end of the line
{enter}Types the Enter key
{esc}Types the Escape key
{home}Shifts cursor to the start of the line
{insert}Positions character to the right of the cursor
{leftarrow}Moves cursor left
{movetoend}Shifts the cursor to end of typeable element
{movetostart}Shifts the cursor to the start of typeable element
{pagedown}Scrolls down
{pageup}Scrolls up
{rightarrow}Shifts cursor right
{selectall}Selects all the text by creating a selection range
{uparrow}Shifts cursor up

Options

We can pass in the objects as options to modify the default behaviour of .type()

OptionDefaultDescription
delay10Option for Delay in time after each keypress
forcefalseForces the action to execute and disables waiting for actionability
logtrueDisplays the logs in the Command log
parseSpecialCharSequencestrueParse special characters for strings surrounded by {}, such as {esc}. You can set the option to false to enter the literal characters.
releasetrueThis option allows to enable a modifier stay activated between commands
scrollBehaviorscrollBehaviorViewport position to where an element to be scrolled before executing any command
timeoutdefaultCommandTimeoutTime to wait for .type() command to resolve before time out
waitForAnimationswaitForAnimationsTo say whether to wait for elements to finish animating before executing any command.
Options for type command

Example

Let us see examples for .type() command

cy.get('textarea').type('Hey there') // enter value in the text area
cy.get('body').type('{shift}') //enables the shift key
cy.get('body').type('{rightarrow}') //type event right arrow 

Cypress Clear Command

Clear command will clear the values in input area or the text field.

Syntax

The syntax for clear command is a follows.

.clear()
.clear(options)

Options

We will look into the options that can be passed to the .clear() command.

OptionDefaultDescription
forcefalseThis will forces the action and disables waiting for actionability to occur
logtrueShows the command in the Command log
scrollBehaviorscrollBehaviorViewport position to where an element must be scrolled to before performing the command
timeoutdefaultCommandTimeoutThis option is the time to wait for .clear() to resolve before time out
waitForAnimationswaitForAnimationsThis will wait for elements to complete animating before executing the command.
Options for clear command

Example

Let us look into the examples for clear command

cy.get('[type="text"]').clear() // Clear input of type text
cy.get('textarea').type('Welcome!').clear() // Clear textarea 
cy.focused().clear() // Clear focused input/textarea

Cypress Check Command

The check command will check or in simpler words, tick the checkboxes or radio buttons. You can uncheck the checkboxes or radio buttons by using the .uncheck() command.

Syntax

We will understand the syntax for check command in Cypress.

//Syntax for check command
.check()
.check(value)
.check(options)
.check(values, options)

//Syntax for uncheck command
.uncheck()
.uncheck(value)
.uncheck(options)
.uncheck(values, options)

Options

The possible options that can be passed to check/uncheck commands are the options same as the clear command listed above

Example

We will look into the example of how we can use check and uncheck commands.

cy.get('[type="checkbox"]').check() // Check checkbox element
cy.get('[type="radio"]').first().check() // Check first radio element
cy.get('[type="radio"]').check('Male') //Check the radio element which has Male
cy.get('[type="checkbox"]').uncheck() //Uncheck checkbox element
cy.get('[type="radio"]').uncheck()  //Uncheck the first radio element
cy.get('[type="checkbox"]').uncheck('Breakfast') // Uncheck the breakfast element

Cypress Select Command

The select Cypress command allows you to select elements within a <select> tag.

Syntax

The following are the syntax for select command

.select(value)
.select(values)
.select(value, options)
.select(values, options)

Options

We can pass in the options to modify the default behaviour of select command.

OptionDefaultDescription
forcefalseThis option forces the action to take place and disables waiting for actionability
logtrueDisplays the logs in the Command log and is set as true by default
timeoutdefaultCommandTimeoutThis option is the time to wait for .select() to resolve before time out
Options for select command

Example

Let us look into examples for the select command

cy.get('select').select('butterfly') // Select the 'butterfly' option
cy.get('select').select(0) // selects the element with 0 index
cy.get('select').select(['parrot', 'peacock']) //selects the parrot and peacock option

Cypress Trigger Command

Trigger command helps to trigger any event on the element.

Syntax

We will look into the syntax for accessing the trigger command

.trigger(eventName)
.trigger(eventName, position)
.trigger(eventName, x, y)
.trigger(eventName, position, options)
.trigger(eventName, options)
.trigger(eventName, x, y, options)

Option

Trigger command accepts all the options that are mentioned for .clear() command. Additionally, there are few options we can configure that are listed below.

OptionDefaultDescription
bubblestrueWhether the event should bubble
cancelabletrueWhether the event can be cancelled
eventConstructorEventThe constructor for creating the event object (e.g. MouseEvent, keyboardEvent)
Option for Trigger command

Example

Let us different ways of using .trigger() in the code.

cy.get('a').trigger('mouseover') // Trigger mouseover event on a link
cy.get('.target').trigger('mousedown', { button: 0 }) //mousedown triggered at button 0
cy.get('button').trigger('mouseup', topRight, { bubbles: false }) //mouseup triggered on topRight position with setting bubble as false

Are Cypress commands async?

All the Cypress commands are asynchronous. They are queued for execution at a later point in time and will not wait for the completion of the commands. Cypress command do not do anything at the time of their invoke,instead they save it for later for execution. You can understand the asynchronous behaviour of Cypress here

Cypress Chainable Commands

In Cypress, we can use a series of commands to interact with elements in DOM. It is imperative to understand how the chaining of commands work internally. If we are chaining commands in a particular line, then Cypress will handle a promise based on the command chain and will yield a command based on the subject to the next command, until the chain of commands end or an error has occurred.

Cypress allows us to click an element or type into elements using the .click() or .type() commands by getting the elements using cy.get() or cy.contains(). Let us see a simple example of chaining commands

cy.get('textarea').type('How are you?')

In the above example, cy.get() is one Cypress command and .type() is another command, where we are chaining the .type() command onto the cy.get() command, telling it to type to the subject that is yielded from the cy.get() element. Similarly, we can chain all the commands that we discussed above.

Chaining Assertion Commands in Cypress

Similar to chaining multiple commands using Cypress, we can also chain assertions with commands. Assertions are commands that let you to describe the expected state or behaviour of the application. Cypress will wait until the elements reach the expected state, and the test will fail if the assertions don’t pass. We will see how we can use chaining commands in asserting an element.

cy.get('button').should('be.disabled') //expect whether the button should be disabled
cy.get('form').should('have.class', 'form-vertical') //expect whether the form should have class as 'form-vertical'
cy.get('input').should('not.have.value', 'Name') // assert whether the input should not have the value 'Name'

As listed above, we are using the cy.get() command and chaining it with the .should() assertion command to expect the behaviour based on the result. This way, we can use chain assertion commands in Cypress.

Cypress Custom Commands

Cypress provides us API’s to create commands based on our requirements. Cypress custom command is similar to the default commands that are pre-existing, except it is user-defined. With custom commands, we can play around with the commands and chain them based on our use case. Cypress custom commands are useful in our workflow if you require reusing them over and over in the tests.

Let us see the syntax for creating a new custom command in Cypress.

Cypress.Commands.add(name, callbackFn)
Cypress.Commands.add(name, options, callbackFn)
Cypress.Commands.overwrite(name, callbackFn)

where the arguments are as follows

name – The name of the command in string that we want to add or overwrite

callbackFn – This function takes an argument passed to the command

options – Pass any options object to define the behaviour of the command

Note : options are supported only for the add commands and do not support for the overwrite commands

OptionAcceptsDefaultDescription
prevSubjectBooleanString or Arrayfalsedefines how to handle the previously yielded subject.

The options that prevSubject accepts are as follows

  • false – ignore previous subjects (parent command)
  • true – accept the previous subjects (child command)
  • optional – pass in whether you want to start a new chain or use an existing chain (dual command)

Parent Custom Command in Cypress

We will see how to add a parent custom command in Cypress. Parent command will always begin a new chain of commands, eventhough you have chained off a previous command. The previously chained command will be ignored and a new command will be chained always. Some of the parent commands are cy.visit(), cy.get(), cy.request(),cy.exec(), cy.route()

Example

We will see an example of how to write a parent custom command in Cypress

Cypress.Commands.add('clickLink', (label) => {
  cy.get('a').contains(label).click()
})
//clicking the "Buy Now" link
cy.clickLink('Buy Now')

In the above example, ‘clickLink‘ is the name of our custom command. It will search for the label. In line 2, the command gets ‘a‘, and search for the link which contains label and click the element. cy.clickLink() will execute the action in the test file and clicks the “Buy Now” link.

Child Custom Command in Cypress

Child Custom commands in Cypress are chained off a parent command or another child command. The subject from the previous command will be yielded to the callback function.

Some of the Cypress commands that can be chained as a child command are .click(), .trigger(), .should(), .find(), .as()

Example

We will look into an example on how to chain a child custom command

Cypress.Commands.add('forceClick', {prevSubject: 'element'}, (subject, options) => {
  // wrap the existing subject and do something with it
  cy.wrap(subject).click({force:true})
})
//accessing the forceClick in the test file
cy.get("[data-test='panel-VALUES']").forceClick();

In the above example, we are naming our custom command as ‘forceClick‘. We are passing the prevSubject argument to the element and wrapping the existing subject. With cy.wrap(), we are force clicking the subject. Then in the test file, we are accessing the custom command, ‘forceClick‘ on a cy.get() command.

Dual Custom Commands in Cypress

Dual custom commands are hybrid between a parent and child command. You can begin a new chain of commands or chain off an existing command. Dual commands are helpful if we want our command to work in different ways with or without the existing subject.

Some of the commands that can be used for dual commands are cy.contains(), cy.screenshot(), cy.scrollTo(), cy.wait()

Example

Let us see an example of how to use dual custom commands

Cypress.Commands.add('getButton', {
  prevSubject: 'optional'
}, (subject) => {
  if (subject) {
   cy.get(subject).get('btn').its('button');
  } else {
    cy.get('btn').its('button');
  }
})

In some cases, we will require to get the button of the text using getButton which will acquire all the button of the element. Now we can use getButton to chain the with the parent element or chain the child element, where it can invoke the elements of the parent.

Since the prevSubject is optional, we can either pass the subject as an argument or invoke the command without the subject in the test file as below

cy.getButton() // without the subject
cy.get('#loginBtn').getButton() // with the subject

Overwriting Existing Cypress Commands

We can overwrite the already existing Cypress commands and modify the behaviour in order to avoid creating another command that will try to use the original command at the end.

Some of the original Cypress command that can be overwritten are cy.visit(), cy.type(), cy.screenshot(), cy.contains()

Example

Let us see an example on how we can overwrite the existing Cypress command.

Cypress.Commands.overwrite('contains',
  (originalFn, subject, filter, text, options = {}) => {
    // determine if a filter argument was passed
    if (typeof text === 'object') {
      options = text
      text = filter
      filter = undefined
    }
    options.matchCase = false
    return originalFn(subject, filter, text, options)
  }
)

As we saw above, we are using the Cypress.Commands.overwrite to modify the existing Cypress command. We are naming our custom command as contains and we are passing arguments to determine whether the filter argument has passed.

Cypress Import Commands

In this section, we will understand how to import Cypress Commands.

We must create our Cypress custom commands in the cypress/support/commands.js file. We shall add the custom commands in the command.js file and import in our test case file to use it.

anysnap 01 oct 2021 at 4 03 59 pm
Command.js file

Cypress Custom Commands with Example

We will understand how to create a custom command and use it in our spec file with real-time example.

As we saw above, we have to add new custom commands under the commands.js file. In that file, let us add a custom command for a login function

Cypress.Commands.add("login", (username, password) => {
    //adding a new command named login
    cy.get('[id=Email]').clear();
    cy.get('[id=Email]').type(username);
    cy.get('[id=Password]').clear();
    cy.get('[id=Password]').type(password);
    cy.get('[type=submit]').click();
  });
image
Custom commands in command.js file

In the above code, we are naming our custom command as login. Inside the custom command, we have added the steps of clearing the username field and entering value in the textfield. Similarly, we are clearing the field and adding the password in the password field. Later, we are clicking the submit button. This is a simple custom command that accepts two arguments : username and password. We will be passing the value for the username and password in our spec file.

Now let us create a spec file named customCommand.spec.js under integration folder. Our spec file will contain the following code

describe("Custom Commands Example", () => {
    it("should login using the custom commands", () => {
      cy.visit("https://admin-demo.nopcommerce.com/");
      cy.login("[email protected]", "admin");
      cy.url().should('be.equal', 'https://admin-demo.nopcommerce.com/admin/')
    });
  });
anysnap 01 oct 2021 at 4 34 30 pm
Spec file accessing the custom command

As we saw above, we are accessing our custom command as cy.login() ,where we are passing the values of username and password.

Cypress Custom Commands IntelliSense

IntelliSense provides intelligent code suggestions in the IDE or code editor directly while we are writing tests. It helps by showing a popup that displays the command definition, link to the documentation page and code examples. If we are using any modern code editor like Visual Studio Code or IntellJ, then IntelliSense will be very useful.

IntelliSense uses Typescript to understand and displays the syntax. If we write custom commands and provide TypeScript definitions for the custom commands, we can use the triple slashes to display IntelliSense, even if our project uses JavaScript only.

To configure IntelliSense, we need to describe the code in cypress/support/index.d.ts file.

// type definitions for Cypress object "cy"
/// <reference types="cypress" />
declare namespace Cypress {
    interface Chainable<Subject> {
      /**
       * Login with credentials
       * @example
       * cy.login(username,password)
       */
      login(username: String, password: String): Chainable<any>
    }
  }

Now, we should let our spec files know that there are some Typescript definitions in the index.d.ts file. So, at the beginning of our spec file, add the below code to let IntelliSense provide suggestions for us.

// type definitions for custom commands like "login"
// will resolve to "cypress/support/index.d.ts"
// <reference types="../support" />
anysnap 01 oct 2021 at 5 06 15 pm
Suggestion provided by IntelliSense

As we saw above, IntelliSense provides us with the arguement we provided in our command.js file and helps in auto-completing.

Step By Step Page Object Model in Cypress with Examples

PAGE OBJECT MODEL 300x212 1

Page Object Model, commonly known as POM, is a popular pattern in any automation framework. Page Object Model can be applied in Cypress too. Page Object Model has many advantages in creating a framework for test automation, such as reducing code duplication and increasing maintainability and readability. Cypress provides us the flexibility to incorporate Page Object Model in the test script. In this article, we will look at creating a Page Object Model in Cypress step by step with examples.

Table of Contents:

cypress page object model
Cypress Page Object Model

What is Page Object Model?

Page Object Model is a design pattern where the page objects are separated from the automation test scripts. Automation testing gives us many leverages that benefit us in testing; however, there are some outcomes such as code duplication and an increase in the risk of maintainability as the project grows. Let us understand the significance of POM with an example.

Consider we have multiple pages in our application like Login Page, Registration Page, and Book Flights page.

  • The Login page contains all the web elements of the login functionalities
  • The Registration contains all the methods and web elements of the registration process
  • The Book flights contain the web elements of the flight booking page

There are three test cases, namely TC1, TC2, and TC3.

  • TC1 contains the login test cases.
  • TC2 contains login and registration test cases
  • TC3 contains login, registration, and flight booking test cases
Flight booking
Example without POM

Now, the login page interacts with TC1.

Registration page needs to interact with TC1 and TC2, and

The flight booking page needs to interact with TC1, TC2, and TC3

As you can see, there are common functionalities between all three test cases. Instead of writing the methods and locators of login in all the test case files, we can have them separately and access them across the files. This way, the code is not repeated, and it is easily readable.

One of the best practices in coding is a concept called DRY. It means Do Not Repeat Yourself. As the full form clearly says, we should not repeat the lines of code again and again. To overcome this, Page Object Model plays an important role in best coding practices.

Page Object Model Framework Architecture

The page object model framework architecture is a proven architecture that can customize with simple methods. Today, almost all companies follow agile methodologies, which involve continuous integration, development, and testing. The automation testers maintain the test framework to work alongside the development process with the Page Object Model. It is a significant design pattern in maintaining the automation test framework as the code grows with new features.

The page object is a design pattern that is an object-oriented class that interacts with the pages of the application we are testing. Page Object comprises of Page Class and Test casesPage class consists of methods and locators to interact with the web elements. We create separate classes for every page in the application. We will be creating individual methods for each functionality and access them in our spec file.

Page Class
Page Object Model

Advantages of using Page Object Model in Cypress

  1. The methods are reusable across the whole project and easy to maintain when the project grows. The lines of code become less readable and optimized.
  2. Page Object Pattern suggests that we separate the operations and flow that we are performing in the UI from verification steps. When we follow the POM pattern, we tend to write clean and easily understandable code.
  3. With the Page Object Model, objects and test cases are independent of each other. We can call the objects anywhere across the project. This way, if we are using different tools like TestNG/JUnit for functional testing or Cucumber for acceptance testing, then it is easily accessible.

Step By Step Page Object Model Cypress with Example

This section will understand how to create a Page Object Model in Cypress with real-time examples that we can implement in projects. We will understand from the basic setup and step-by-step process for creating a Page Object Model.

Let’s discuss the scenario on which we will write the functions in this example.

  1. Navigate to https://admin-demo.nopcommerce.com/ website
  2. Enter valid username and password
  3. Click on the Login Button
  4. Validate the URL whether it is appended with /admin after login

We will be creating two files – one PageObject file and one spec file for this example. Let us begin!

Step 1: Open our project in VS code. Create a folder called PageObject under the integration folder. Under this folder, you can create page object files for any modules.

anysnap 26 aug 2021 at 7 08 10 pm
New folder named PageObject

Step 2: Create a file named LoginPage.js under the PageObject folder. In LoginPage.js, we will be writing the methods that involve the login functionalities.

anysnap 26 aug 2021 at 8 33 13 pm
LoginPage.js creation under PageObject folder

Step 3: Let’s start writing our first test method in the LoginPage.js file. We have to first create a class that we will be exporting in our spec file. We will call our class as LoginPage

class LoginPage {
}

Based on our pseudocode, our first step is to navigate to the URL. We will call our method as navigate(). Inside our navigate method, we shall add the cy.visit() function from Cypress.

 navigate() {
        cy.visit('https://admin-demo.nopcommerce.com/')
    }

anysnap 26 aug 2021 at 8 51 29 pm
navigate method

Step 4: Now, we will have to enter the username in our email field. We will name our method as enterEmail(). First, we should get the locator of the email field and access them via cy.get() command. Then we will clear the field using the clear() command and add the username using the type() command. In our method, we pass a parameter username to pass the value in the spec file. This way, we are keeping it generic to access this method if a different email id is required.

enterEmail(username) {
        cy.get('[id=Email]').clear()
        cy.get('[id=Email]').type(username);
        return this
    }

Instead of writing the cy.get() command twice in the above code, we can simply loop them with the dot operator.

  enterEmail(username) {
        cy.get('[id=Email]')
            .clear()
            .type(username);
        return this
    }

anysnap 26 aug 2021 at 9 01 21 pm 1
enterEmail method

You might have noticed return this in line 9. this indicates that the enterEmail method belongs to the particular LoginPage class. Basically, this represents the class.

Step 5: We have to create a method for passwords similar to our enterEmail method. We will call our password method as enterPassword(). Initially, we will get the locator for the password, clear the field and type the input value. We will pass a parameter to our method called pswd and access in the type() command.

enterPassword(pswd) {
    cy.get('[id=Password]')
        .clear()
        .type(pswd)
    return this
}
Screenshot 2021 08 26 at 9.54.47 PM
enterPassword method

Step 6: Our last method would be to click on the login button. We shall name our method as submit(). We will get the locator and click the button using the click() method from Cypress.

 submit() {
        cy.get('[type=submit]').click()
    }

Screenshot 2021 08 26 at 9.57.55 PM
submit method

Step 7: Now, we have to export this class to use it across our spec file. For this, we just add one line outside our class, and we can easily access it in our spec file.

export default LoginPage

Screenshot 2021 08 26 at 10.01.24 PM
export command

Hurray! We have created a Page Object file for our project. It was pretty simple and easy!

Accessing the Page Objects in the Spec file

Now let us move on to our test case file. We have to create a spec file in our integration folder. We shall call our spec file POMDemo.spec.js.

anysnap 27 aug 2021 at 12 01 59 pm
POMDemo.spec.js file creation

Step 1: To access our methods in the LoginPage.js file, we must import them into our spec file. We import by using the import statement. We should navigate to the LoginPage.js file by using ../

In our case, the path is ../integration/PageObject/LoginPage. So, the import statement will look something like the below.

import LoginPage from "../integration/PageObject/LoginPage"

Step 2: Since we use Mocha, we will write our test case inside describe() and it() block. describe() represents a test suite, and it() represents a test case. Both the blocks are a function and accept a string parameter that includes the description of the test.

describe("Cypress POM Test Suite", function () {
})

anysnap 27 aug 2021 at 12 17 00 pm
Describe block

Inside the describe block, we will write our it() by adding the description as login with valid credentials.

it("Login with valid credentials", function () {
       
    })

anysnap 27 aug 2021 at 12 20 54 pm
it block

Step 3: To access our methods from our Page object file, we should create an instance for our Login class. To create an instance for the login class, we must declare a variable and assign it to our class file using the new keyword. With the declared variable, we can easily access the methods from the Page object file.

                                               const login = new LoginPage();
anysnap 27 aug 2021 at 1 05 50 pm
Instance of a class

Note: With the variable login, we can access the methods from the Page object class. When we start typing login. , the vscode will list the suggestions of all the methods available in the LoginPage.js file. This helps us to verify that we have exported and imported our class properly!

Step 4: Let us call our navigate() method to visit the URL. This is the first action in our test case.

/// <reference types="cypress" />
import LoginPage from "./PageObject/LoginPage"
describe("Cypress POM Test Suite", function () {
    it("Login with valid credentials", function () {
        const login = new LoginPage();
        login.navigate();
    });
});

Step 5: We should enter the username in the email field. We access the enterEmail() with the login object. enterEmail() method accepts a parameter username. So we should pass the value for the username as a string in our spec file

/// <reference types="cypress" />
import LoginPage from "./PageObject/LoginPage"
describe("Cypress POM Test Suite", function () {
    it("Login with valid credentials", function () {
        const login = new LoginPage();
        login.navigate();
        login.enterEmail('[email protected]');
    })
})

Step 6: Similar to step 5, we should call our enterPassword() method by passing the password as a parameter in the string.

/// <reference types="cypress" />
import LoginPage from "./PageObject/LoginPage"
describe("Cypress POM Test Suite", function () {
    it("Login with valid credentials", function () {
        const login = new LoginPage();
        login.navigate();
        login.enterEmail('[email protected]');
        login.enterPassword('admin');
    })
})

Step 7: Next, we have to click on the login button. We will call the method submit() from our page object file.

/// <reference types="cypress" />
import LoginPage from "./PageObject/LoginPage"
describe("Cypress POM Test Suite", function () {
    it("Login with valid credentials", function () {
        const login = new LoginPage();
        login.navigate();
        login.enterEmail('[email protected]');
        login.enterPassword('admin');
        login.submit();
    })
})

Step 8: After logging in, we have to assert the URL. We will verify whether the URL is equal to the URL after login. For assertion, we will use the Chai assertion library, which is inbuilt with Cypress.

/// <reference types="cypress" />
import LoginPage from "./PageObject/LoginPage"
describe("Cypress POM Test Suite", function () {
    it("Login with valid credentials", function () {
        const login = new LoginPage();
        login.navigate();
        login.enterEmail('[email protected]');
        login.enterPassword('admin');
        login.submit();
        cy.url().should('be.equal', 'https://admin-demo.nopcommerce.com/admin/')
    })
})

anysnap 27 aug 2021 at 4 39 36 pm
Login test case

The above image represents the login test case. We were able to write a test case with a Page Object Model with very few simple steps. Now let us run the test case and see the result.

We shall open the Cypress test runner and click on the spec file and run our test case. Check this article on how to open Cypress test runner.

anysnap 27 aug 2021 at 1 41 55 pm 2
Test Result in Cypress

Hurray! We have successfully written a test case that uses Page Object Model in Cypress. We can incorporate this pattern in real-time projects. There are many ways that we can write the methods in a page object file. I have shown you an example that is standard and works for any project. You can also write only the return function in the page object file and then click and type directly in our spec file.

We will see another pattern that we can use in the project. This method will also work perfectly fine.

In this type, we will be returning only the locator function in our method and perform actions in the test file. We will write code for the same scenario we saw above.

Page Object – LoginPage.js

class LoginPage {
    navigate() {
        cy.visit('https://admin-demo.nopcommerce.com/')
    }
    enterEmail() {
        return cy.get('[id=Email]')
    }
    enterPassword() {
        return cy.get('[id=Password]')
    }
    submit() {
        return cy.get('[type=submit]')
    }
}
export default LoginPage

As we saw above, we are writing only the locator inside our function and returning them. The return represents that the particular method belongs to the class LoginPage.js. We are not adding any actions in our methods.

anysnap 27 aug 2021 at 4 48 05 pm
Page Object File example

Spec File – POMDemo.spec.js

We will look into the example of accessing the methods in the spec file.

/// <reference types="cypress" />
import LoginPage from "./PageObject/LoginPage"
describe("Cypress POM Test Suite", function () {
    it("Login with valid credentials", function () {
        const login = new LoginPage();
        login.navigate();
        login.enterEmail().clear()
        login.enterEmail().type('[email protected]');
        login.enterPassword().clear()
        login.enterPassword().type('admin');
        login.submit().click();
        cy.url().should('be.equal', 'https://admin-demo.nopcommerce.com/admin/')
    });
});

Screenshot 2021 08 28 at 7.35.20 PM
Spec file Example

Here, we call the method from the PageObject file and perform the test case actions. So first, we are calling our reference variable login and then appending it with the method enterEmail() and finally appending the action type. In our type(), we are passing the username value.

anysnap 27 aug 2021 at 1 41 55 pm 3
Test Result

As you can see, all the commands have been executed, and the test case has passed!

You can choose whichever Page Object Model suits your project and your opinion. There is no particular rule to stick to only one procedure.

How to use Fixtures as a Test Data Source in Page Object Model in Cypress?

In our Page Object Model examples, we passed the username and password value directly in either the Page Object file or directly in the test case file. This section will understand how to use fixtures in Cypress to keep the data safe and not exposed. We should try to keep all the credentials and data in one file and access them. This way, it is easy to maintain, and sensitive data like username and password are not exposed. This method is also one of the procedures that we need to follow in Page Object Pattern.

As discussed earlier, Fixture helps store data in a JSON file or excel file, or an external library like Apache POI. We will use these data by creating a variable and access them in our spec file. Let us understand with an example.

Cypress provides a folder called “fixtures.” We will create a JSON file called credentials.json under the ‘Fixtures’ folder.

Screenshot 2021 08 28 at 6.58.39 PM
JSON file creation

Let us declare our username, password, and URL values that we need to validate in a JSON format in the credentials.json file.

{
    "username" : "[email protected]",
    "password" : "admin",
    "adminUrl" : "https://admin-demo.nopcommerce.com/admin/"
}

Screenshot 2021 08 28 at 7.30.53 PM
Passing values in the credentials.json file

Accessing the values from the JSON file in the test case file

As we have defined the values in our JSON file, we will access them in our test case file using Fixtures from Cypress. We will access the JSON value with this keyword. Let’s wrap the fixture function in a before() block.

describe("Cypress POM Test Suite", function () {
 
before(function () {
        cy.fixture('credentials').then(function (testdata) {
            this.testdata = testdata
        })
})

cy.fixture(‘credentials’).then(function (testdata) { this.testdata = testdata }) – this line represents that we are passing the credentials.json file as a parameter to our cy.fixture() command. Here, we are not required to pass whether it is a JSON file. Just pass the file name alone. Later, we pass testdata as a parameter in the function and access the testdata variable using this.

/// <reference types="cypress" />
import LoginPage from "./PageObject/LoginPage"
describe("Cypress POM Test Suite", function () {
    before(function () {
        cy.fixture('credentials').then(function (testdata) {
            this.testdata = testdata
        })
    })
    it("Login with valid credentials", function () {
        const login = new LoginPage();
        login.navigate();
        login.enterEmail(this.testdata.username)
        login.enterPassword(this.testdata.password)
        login.submit();
        cy.url().should('be.equal', this.testdata.adminUrl)
    });
});

login.enterEmail(this.testdata.username) – This will fetch the username value from the credentials.json file and fill it into the email field.

login.enterPassword(this.testdata.password) – This will fetch the password value from the credentials.json file and fill it into the password field

cy.url().should(‘be.equal’, this.testdata.adminUrl) – This will get the adminUrl from the credentials.json file and validate in the assertion

Screenshot 2021 08 28 at 7.32.17 PM
Passing the data from JSON file to spec file

Now, let us run the test case for the result.

anysnap 27 aug 2021 at 1 41 55 pm 4
Test result

As we can see, the test cases have been executed and have passed. This example will help you to write a basic Data-driven test case. You can incorporate it in your project using this method. You can create new JSON files under the Fixture folder, add values related to test data, and access it across any test file.

Frequently Asked Questions

Does Cypress support Page Object Model?

Of course. Cypress gives all the flexibility to play around with pages and objects in the repository. It is easy to implement.

Which Page Object Model should I use from the above examples?

There is no particular rule to stick to only one way of Page Object Model. You can use any model that has been discussed above. You are free to customize the model according to your project.

Why should I use fixtures in the Page Object Model in Cypress?

Fixture helps store sensitive data like username, password, and URLs in a separate file like JSON or excel. This ensures the application’s security and access them easily in any files across the project. To access the JSON file, we use fixtures to use it in our spec file.