In this Blog, I’ll walk you through the process of fetching an email link and OTP from Email using Python. Learn how to fetch links & OTP from email efficiently with simple steps. Email and OTP (One-Time Password) verification commonly ensure security and verify user identity in various scenarios.
Some typical scenarios include:
User Registration
Password Reset
Two-factor authentication (2FA)
Transaction Verification
Subscription Confirmation
We’ll leverage the imap_tools library to interact with Gmail’s IMAP server. We’ll securely manage our credentials using the dotenv library. This method is efficient and ensures that your email login details remain confidential.
Store Credentials Securely to Fetch OTP from Email:
A .env file is typically used to store environment variables. This file contains key-value pairs of configuration settings and sensitive information that your application needs to run but which you do not want to hard-code into your scripts for security and flexibility reasons.
Create a .env file in your project directory to store your Gmail credentials.
EMAIL_USER=your-email@gmail.com
EMAIL_PASS=your-password
How to Create and Use an App Password for Gmail
To securely fetch emails using your Gmail account in a Python script, you should use an App Password.
This is especially important if you have two-factor authentication (2FA) enabled on your account.
Here’s a step-by-step guide on how to generate an App Password in Gmail:
Go to your Google Account settings.
Select “Security” from the left-hand menu.
Enable Two-Factor Authentication:
Go to your Google Account Security Page.
Under the “Signing in to Google” section, ensure that 2-Step Verification is turned on. If it’s not enabled, click on “2-Step Verification” and follow the instructions to set it up.
Generate an App Password:
Once 2-step Verification is enabled, return to the Google Account Security Page.
Under the “Signing in to Google” section, you will now see an option for “App passwords.” Click on it.
You might be prompted to re-enter your Google account password.
In the “Select app” dropdown, choose “Mail” or “Other (Custom name)” and provide a name (e.g., “Python IMAP”).
In the “Select device” dropdown, choose the device you’re generating the password for, or select “Other (Custom name)” and enter a name (e.g., “My Computer”).
Click on “Generate.”
Google will provide you with a 16-character password. Note this password down securely, as you’ll need it for your Python script.
Load Environment Variables:
In your Python script, use the dotenv library to load these credentials securely. Here’s how you can do it:
from dotenv import load_dotenv
from imap_tools import MailBox, AND
import os
# Load .env file
load_dotenv()
# Read variables
email_user = os.getenv('EMAIL_USER')
email_pass = os.getenv('EMAIL_PASS')
Loading Environment Variables:
The dotenv library is used to load the email username and password from the .env file. This approach keeps your credentials secure and out of your source code.
Connect to Gmail and Fetch Emails:
We will create a function to connect to Gmail’s IMAP server and fetch the latest unread email. The function will look like this:
def check_latest_email():
# Connect to Gmail's IMAP server
with MailBox('imap.gmail.com').login(email_user, email_pass, 'INBOX') as mailbox:
# Fetch the latest unread email
emails = list(mailbox.fetch(AND(seen=False), limit=1, reverse=True))
if len(emails) == 0:
return None, None, None # No Emails Found
return emails[0]
if __name__ == "__main__":
email = check_latest_email()
if email:
print("Email subject: ", email.subject)
print("Email text: ", email.text)
print("Email from: ", email.from_)
else:
print("No new emails found.")
Connecting to Gmail’s IMAP Server:
Using the imap_tools library, we connect to Gmail’s IMAP server.
The MailBox class handles the connection.
The login method authenticates using your email and password.
Fetching the Latest Unread Email:
The fetch method retrieves emails based on specified criteria.
AND(seen=False) ensures we only get unread emails.
limit=1 fetches the latest one.
reverse=True sorts the emails in descending order.
Handling Email Data:
The function check_latest_email returns the most recent unread email’s subject, text, and sender.
If no new emails are found, it returns None.
By following these steps, you can efficiently fetch the latest unread email from your Gmail inbox using Python.
This method is not only secure but also straightforward, making it easy to integrate into your projects.
Fetching the link from email:
def extract_link(email_text):
# Regex pattern to match URLs
url_pattern = re.compile(r'https?://[^\s]+')
match = url_pattern.search(email_text)
if match:
return match.group()
return None
#Example to fetch link from email content:
link = extract_link(email.text)
if link:
print("Extracted Link: ", link)
else:
print("No link found in the email content.")
Fetching OTP from email:
Create a function to extract the OTP from the email content using a regular expression. This assumes the OTP is a 6-digit number, which is common for many services:
def extract_otp(email_text):
# Regex pattern to match a 6-digit number
otp_pattern = re.compile(r'\b\d{6}\b')
match = otp_pattern.search(email_text)
if match:
return match.group()
return None
#Example to extract otp from email
otp = extract_otp(email.text)
if otp:
print("Extracted OTP: ", otp)
else:
print("No OTP found in the email content.")
Refer to the following GitHub repository for instructions on how to fetch links and OTPs from Gmail.
Fetching links and OTPs from email content programmatically is essential for enhancing security, improving user experience, and increasing operational efficiency. Automation ensures timely and accurate processing, reducing the risk of errors and phishing attacks while providing a seamless user experience. This approach allows businesses to scale their operations, maintain compliance, and focus on strategic activities.
Click here for more blogs on software testing and test automation.
Harish is an SDET with expertise in API, web, and mobile testing. He has worked on multiple Web and mobile automation tools including Cypress with JavaScript, Appium, and Selenium with Python and Java. He is very keen to learn new Technologies and Tools for test automation. His latest stint was in TestProject.io. He loves to read books when he has spare time.
Setting up Appium for testing on real devices for android app automation can be tricky. Many testers struggle with installing the right software, setting environment variables, and connecting their devices properly. These issues can cause a lot of frustration and slow down the testing process.
In this blog, we’ll make it easy for you. We’ll walk you through each step, from installing necessary software like the Java Development Kit (JDK) and Android Studio, to setting up your Android device for android app automation. We’ll also show you how to install Appium, configure it correctly, and use tools like Appium Inspector to interact with your app.
By following this simple guide, you’ll be ready to test your mobile apps on real devices quickly and efficiently.
What is Appium testing in Android App Automation
Appium is an open-source automation tool used for testing mobile applications. It allows testers to automate native, hybrid, and mobile web applications on iOS and Android platforms using the WebDriver protocol. Appium provides a unified API (Application Programming Interface) that allows you to write tests using your preferred programming language (such as Java, Python, JavaScript, etc.) and test frameworks. It supports a wide range of automation capabilities, including gestures, device rotation, multi-touch actions, and handling various types of mobile elements. Appium enables cross-platform testing, where the same tests can be executed on multiple devices, operating systems, and versions, providing flexibility and scalability in mobile app testing or android testing.
Advantages of Using Appium in Android App Automation:
Appium is an open source and free tool available for testers and developers.
Appium supports both real device and emulators/simulators testing.
Appium is compatible with popular testing frameworks and tools, making it easy to integrate into existing testing workflows and environments.
Advantages of using real device for Android App Automation:
Real device allows you to check your application under different network like 2G,3G,4G and 5G.
Using real device we can test hardware specific features like GPS, fingerprint and camera.
Using a real device provides more accuracy by taking some factors into consideration like device battery, processor, memory and device size.
Step→1
Install Java Development Kit (JDK):
Download and install the latest JDK from the official Oracle website.
Set JAVA_HOME as environment variable.
Also add jdk’s bin folder path in Path environment variable.
Step→2
Install Android Studio:
Download and install Android Studio from the official Android website.
After successful installation now we will set the ANDROID_HOME environment variable.
Also put platform tools path in path variable.
Now open cmd and run adb in command line and it should get executed successfully.
Step→3
Install Node.js:
If you haven’t already installed Node.js, you can download and install it from the official Node.js website.
Once the installation is complete check node version using command node -v also npm -v.
Step→4
Install Appium for real device testing using command npm install -g appium in command line:
Verify appium version using appium -v in command line.
Now run the command appiumin command line using this command your server should start and we are ready to do testing.
Step→5
Install Appium for real device testing using command npm install -g appium in command line:
Now run appium-doctor in command lineto check weather every dependency required for appium has been installed successfully.
Step→6
Now we need to install UIAutomator driver which allows to interact with the UI elements of Android apps during automated testing. It provides improved stability and performance compared to the original UIAutomator driver. To install it use this command appium driver install uiautomator2 in command line.
Step→7
Now for real device testing we also need to make some changes on device side too so we need to enable developer option for this:
Open setting and click on about phone.
Click on software information.
Click on Build number 5 times to enable developer mode.
Now once this option is enabled we need to enable usb debugging option as well.
Note: Above information to enable the developer mode its for SAMSUNG device it will be different for other device type.
What is Appium Inspector in Android App Testing?
Appium inspector is a tool which provides testers with a graphical user interface for inspecting and interacting with elements within mobile applications.
Step→8
Install appium inspector for windows using below link appium inspector.
Step→9
Start the appium session using command appium -a 127.0.0.1 -p 4723
Alternatively we can use appium GUI Appium GUI to start the server
i. Enter the host as 127.0.0.1
ii. Enter port number as 4723
iii. If you are using Appium GUI for start server.we need to also add remote path for Appium inspector
Step→10
Open the appium inspector enter remote host as 127.0.0.1 and port as 4723.
Configuring Desired Capabilities using Appium for Android App Automation:
When setting up automation with Appium for Android devices, it’s crucial to define the desired capabilities appropriately. These capabilities act as parameters that instruct Appium on how to interact with the device and the application under test.
deviceName: This parameter specifies the name of the device being used for testing. It’s essential to provide an accurate device name to ensure that Appium connects to the correct device.
udid: The Unique Device Identifier (UDID) uniquely identifies the device among all others. Appium uses this identifier to target the specific device for automation. Make sure to input the correct UDID of the device you intend to automate.
platformName: Here, the platform name is set to “Android,” indicating that the automation is targeted towards the Android platform.
platformVersion: This parameter denotes the version of the Android platform installed on the device.
automationName: Appium supports multiple automation frameworks, and here, “UiAutomator2” is specified as the automation name. UiAutomator2 is a widely used automation framework for testing Android apps.
appPackage: The app package is the unique identifier for the application under test. It’s essential for Appium to know which app to launch and interact with during automation.
appActivity: This parameter specifies the main activity of the application that needs to be launched.
For device udid run adb device command in command line
For device name and version we can check software information from android settings
For application package and appActivity we can download Apk Info application from play store
For application bundle Id and App activity
Step→11
Once you enter the remote host and port number enter below capabilities to open calculator application from your android devic for android testing.
The images below illustrate how I started the Appium server using the Appium GUI and successfully opened the Calculator app in Appium Inspector with the specified capabilities and now it’s ready to inspect your app to prepare for automated testing efficiently.
Conclusion:
Setting up Appium for testing on real Android devices can initially seem daunting due to the numerous steps involved and the technical nuances of configuring software and environment variables. However, by following this step-by-step guide, the process becomes manageable and straightforward.
Investing the time and effort to configure Appium correctly pays off by significantly enhancing the efficiency and effectiveness of your mobile testing strategy. This setup not only improves the
Click here for more blogs of software testing and test automation.
Junior Software Development Engineer in Test (JR. SDET) with 1 year of hands-on experience in automating and testing mobile applications using Python and Appium. Proficient in Selenium and Java, with a solid understanding of real device testing on both iOS and Android platforms. Adept at ensuring the quality and performance of applications through thorough manual and automated testing. Skilled in SQL and API testing using Postman.
After spending years in the software testing field, many SDETs/Test Engineers showcase strong technical abilities and hard work. However, despite their skill and effort, some may find themselves feeling undervalued, lacking the recognition and success they had hoped for, highlighting the importance of software testing skills.
Conversely, there are also SDETs/Test Engineers who possess solid technical knowledge and have rapidly gained recognition for their contributions, resulting in significant career advancement. What do you believe sets them apart? Could it be luck, connections, a positive reputation with seniors, or another factor?
Indeed, a crucial distinction lies between the two categories. Individuals in the first group solely emphasize technical skills and hard work, while those in the second group strike a balance between technical expertise and soft skills, allowing them to work smartly.
But what exactly are these soft skills, and why are they pivotal for career growth?
Absolutely, Technical skills are undoubtedly paramount as they form the solid foundation upon which one’s expertise is built. Without acquiring strong technical skills, initiating or sustaining a career in the long run can prove to be quite challenging.
However, it’s essential to recognize that these technical skills must be complemented by Soft skills to maximize outcomes and achieve goals within optimized timelines. Just like hand in hand, the synergy between Technical and Soft skills fosters excellence in work and facilitates goal attainment.
By now, it’s evident that Soft Skills hold immense significance not only in the software testing field but also across various other domains. Despite their importance, these skills are often overlooked amidst work pressure, tight deadlines, and a focus on problem-solving or achieving test results.
Let’s delve into some of the most common Soft skills, well-known to everyone, yet frequently neglected in practice.
Essential Skills in the Software Testing Field
Here are the most common soft skills for software testing professionals:
Let’s dive deeper into each of these skills to understand their significance and how they contribute to success in the software testing field.
1. Attention to detail :
It is a foundational skill in software testing that contributes to the accuracy, reliability, and overall quality of software products. Testers who possess this skill play a crucial role in ensuring that software meets quality standards, satisfies user requirements, and delivers a positive user experience.
Benefits :
Effective Bug Identification: Testers who pay close attention can find even small issues in the software, helping developers fix them faster.
Ensuring Quality: Attention to detail ensures that all parts of the software meet the required standards by carefully reviewing documents and test cases.
Improving User Experience: Testers focus on making sure the software is easy to use and error-free, which makes users happier and more likely to keep using the product.
Identifying Risks Early: By carefully examining requirements and designs, testers can catch potential problems before they become serious issues, saving time and money.
Building Trust: Thorough testing builds trust in the software among clients and users, showing that it’s reliable and high-quality.
Encouraging Improvement: Testers who pay attention to detail help their teams get better over time by learning from mistakes and finding ways to improve their processes.
2. Proactive communication:
In software testing proactive communication involves initiating and maintaining effective communication within the team and with Developers, Clients, and Stakeholders, throughout the testing process.
Benefits :
Improved Team Collaboration: Proactive communication fosters better collaboration among team members, ensuring everyone is on the same page regarding project goals, tasks, and timelines.
Early Issue Identification: By sharing updates and insights regularly, team members can quickly identify potential issues or roadblocks in the testing process, allowing for timely resolution.
Enhanced Problem-Solving: Proactive communication encourages team members to openly discuss challenges and brainstorm solutions, leading to more effective problem-solving and faster resolution of issues.
Increased Efficiency: Clear and proactive communication helps streamline workflows and eliminate misunderstandings, reducing the likelihood of rework or delays in the testing process.
Effective Task Coordination: By communicating task assignments, dependencies, and priorities proactively, team members can coordinate their efforts more efficiently, ensuring that testing activities progress smoothly.
Boosted Morale: Open and transparent communication creates a positive work environment where team members feel valued and supported, leading to higher morale and job satisfaction.
Continuous Improvement: Proactive communication encourages feedback and discussion about testing processes and practices, enabling the team to identify areas for improvement and implement changes to enhance overall efficiency and effectiveness.
3. Good data organizing and presentation skills :
It involves the ability to effectively structure, format, and present data in a clear, concise, and meaningful manner.
Benefits :
Clarity in Reporting: Testers often need to compile and present data regarding test results, defects, and overall testing progress. Strong data organizing skills ensure that information is presented clearly and concisely, making it easier for clients/stakeholders to understand and interpret.
Effective Communication: Well-organized data facilitates effective communication with developers, project managers, and other stakeholders. Testers can convey testing findings and insights more effectively, leading to quicker decision-making and problem-resolution.
Identifying Patterns and Trends: By organizing data systematically, testers can identify patterns, trends, and correlations in software behavior or defect occurrences. This enables them to make more informed decisions about where to focus testing efforts and how to prioritize issues for resolution.
Facilitating Root Cause Analysis: When defects or issues arise, well-organized data allows testers to conduct thorough root cause analysis. They can trace the origins of problems more efficiently, leading to more accurate diagnoses and more effective solutions.
Enhancing Documentation: Good data organizing skills contribute to the creation of comprehensive and well-structured test documentation. Test plans, test cases, and test reports are more informative and useful when data is organized logically and presented in a clear format.
Demonstrating Value: Effective data presentation showcases the value of testing efforts to stakeholders. By presenting data in a compelling and visually appealing manner, testers can demonstrate the impact of their work on software quality, project success, and overall business objectives.
4. Time management :
In the software testing profession time management involves efficiently allocating and prioritizing time to complete testing tasks, meet deadlines, and ensure the timely delivery of high-quality software. Here are the benefits of effective time management in software testing
Benefits :
Meeting Deadlines: Proper time management allows testers to schedule and prioritize tasks effectively, ensuring that testing activities are completed on time and within project deadlines.
Optimizing Resource Allocation: By managing time efficiently, testers can allocate resources, such as human resources and testing tools, in a way that maximizes productivity and minimizes waste.
Enhancing Testing Coverage: With good time management, testers can allocate sufficient time to different testing activities, including test planning, execution, and defect resolution, ensuring comprehensive testing coverage and thorough validation of the software.
Improving Test Quality: Properly managing time allows testers to dedicate adequate time to each testing activity, reducing the likelihood of rushing through tests or skipping important steps. This results in higher-quality testing outcomes and more reliable software.
Identifying Risks Early: Time management enables testers to allocate time for risk assessment and mitigation activities, such as identifying potential risks, creating contingency plans, and conducting risk-based testing. Early identification of risks helps prevent issues from escalating and ensures smoother project execution.
5. Critical Thinking while Planning Tasks:
It plays a crucial role in planning tasks in the software testing profession.
Benefits :
Identification of Test Objectives: Critical thinking helps testers analyze project requirements and objectives thoroughly, ensuring that testing activities are aligned with the goals of the project. This ensures that testing efforts are focused on verifying the functionality, performance, and quality attributes that are most critical to the project’s success.
Effective Test Strategy Development: Critical thinking enables testers to evaluate different testing approaches and methodologies critically, selecting the most appropriate strategy for the given project context. This ensures that testing efforts are efficient, cost-effective, and capable of uncovering potential defects and issues effectively.
Optimized Test Coverage: Critical thinking allows testers to analyze the software under test critically, identifying key areas and functionalities that require testing priority. By prioritizing testing efforts based on criticality and risk, testers can optimize test coverage and ensure that testing resources are allocated effectively.
Risk Assessment and Mitigation: Critical thinking helps testers assess potential risks and vulnerabilities in the software accurately. By critically analyzing project requirements, dependencies, and constraints, testers can identify and prioritize risks, allowing them to develop targeted risk mitigation strategies and allocate testing resources accordingly.
Identification of Test Scenarios: Critical thinking enables testers to identify and define test scenarios comprehensively. They consider various factors such as user workflows, boundary conditions, error handling, and performance requirements. This ensures that testing coverage is thorough. Critical scenarios are adequately tested as a result.
Adaptability to Changes: Critical thinking equips testers with the ability to adapt and adjust testing plans dynamically. They respond to changing project requirements, priorities, or constraints. Testers critically evaluate the impact of changes on testing objectives and strategies. They make informed decisions and adjust testing plans accordingly. This ensures continued alignment with project goals.
6. Adaptability :
In the software testing profession, adaptability in software testing skills is crucial. Testers need to respond effectively to changes. These changes can include project requirements, priorities, technologies, or constraints.
Benefits :
Flexibility in Test Planning: Testers can adapt their testing strategies and plans to accommodate changes in project scope, timelines, or priorities. This ensures that testing efforts remain aligned with evolving project needs and objectives.
Quick Response to Changes: Adaptability allows testers to respond quickly to changes in software requirements, design, or functionality. They can adjust test cases, test scripts, and test data as needed. This ensures comprehensive coverage of new features or modifications.
Efficient Resource Allocation: Testers can adaptively allocate testing resources, such as persons, tools etc based on changing project demands. This ensures that resources are utilized efficiently and effectively to support testing activities.
Effective Risk Management: Adaptability enables testers to identify and respond proactively to emerging risks or challenges in the testing process. They can adjust testing priorities, focus areas, or methodologies to mitigate risks and ensure they adequately address critical areas.
Enhanced Problem-Solving: Adaptability fosters a problem-solving mindset among testers, enabling them to overcome obstacles or challenges encountered during testing. They can explore alternative approaches, techniques, or tools to address complex testing scenarios effectively.
Continuous Improvement: Adaptability promotes a culture of continuous improvement within testing teams. Testers actively seek feedback, reflect on past experiences, and implement changes to enhance testing processes and practices over time.
Customer Satisfaction: Adaptable testers respond to feedback from end-users or clients. They incorporate preferences or requirements into the testing process. This leads to higher levels of customer satisfaction. It ensures that the software meets user needs effectively.
7. Empathy and customer-centric approach :
In the software testing profession, an empathy and customer-centric approach involves considering the perspective, needs, and experiences of end-users throughout the testing process.
Benefits :
Improved User Satisfaction: Testers can ensure that the software meets users’ needs effectively. This is done by understanding their perspective and requirements. It leads to higher levels of user satisfaction.
Enhanced Usability: Taking an empathetic approach helps testers identify usability issues early in the testing process. This allows for improvements that result in a more user-friendly software interface.
Better Bug Detection: Testers who empathize with users are more likely to anticipate how they will interact with the software. This leads to better identification of potential bugs or defects. These issues could affect user experience.
Enhanced Brand Loyalty: Users develop a sense of loyalty to the brand when they feel that the software understands and addresses their needs. They are more likely to stay committed and engaged. This loyalty often leads to repeat business and positive word-of-mouth referrals.
Alignment with Business Goals: An approach centered around the customer ensures that software testing efforts align with broader business goals. These goals may include increasing revenue, improving market share, or enhancing customer satisfaction.
Conclusion:
In conclusion, software testing skills encompass expertise in various testing methodologies. Technical skills equip you with the knowledge to execute these methodologies effectively. Soft skills complement your efforts by meticulously organizing details in a presentable manner. They also enhance your flexibility and adaptability to navigate dynamic changes in client requirements. This ensures the delivery of a product that meets the end user’s expectations. Therefore, achieving a perfect balance between technical and soft skills is pivotal for recognition and advancement in your career.
Click Here to read more blogs for Software Testing Tips and Practices.
Manisha is a Lead SDET at SpurQLabs with overall experience of 3.5 years in UI Test Automation, Mobile test Automation, Manual testing, database testing, API testing and CI/CD. Proven expertise in creating and maintaining test automation frameworks for Mobile, Web and Rest API in Java, C#, Python and JavaScript.
Understanding 2FA Authenticator Apps and Time-based One-Time Passwords (TOTP)
2FA Login using TOTP: In an era where cybersecurity is paramount, two-factor authentication (2FA) has become a cornerstone of online security. Authenticator apps and Time-based One-Time Passwords (TOTP) offer an additional layer of protection beyond traditional password-based security measures. This guide aims to elucidate the concept of 2FA authenticator apps, delve into the workings of TOTP, and provide insights into their importance in digital security.
What are 2FA Authenticator Apps?
Authenticator apps generate time-based one-time passwords (TOTPs) on mobile devices for authentication. They serve as a secure means of implementing 2FA, requiring users to provide both something they know (their password) and something they have (their mobile device with the authenticator app installed).
How Do 2FA Authenticator Apps Work?
Initialization: When setting up 2FA for an online account, users typically scan a QR code or manually enter a secret key provided by the service into their authenticator app.
Code Generation: Once initialized, the authenticator app generates TOTPs based on a shared secret key and the current time. These TOTPs are typically six-digit codes that change every 30 seconds.
Authentication: During login, users enter the current TOTP from their authenticator app along with their password. The service verifies the entered TOTP against the expected value based on the shared secret key.
Time-based One-Time Passwords (TOTP):
TOTP generates short-lived authentication codes using a shared secret key and the current time. The algorithm combines the secret key with the current time interval to produce a unique, one-time password that is valid only for a brief period, typically 30 seconds. TOTP ensures that even if an attacker intercepts a generated code, it quickly becomes obsolete, enhancing security.
Importance of Authenticator Apps and TOTP:
Enhanced Security: Authenticator apps provide an additional layer of security beyond passwords, significantly reducing the risk of unauthorized access to online accounts.
Protection Against Phishing: Because TOTP codes generate locally on your device and change with time, they resist phishing attacks that aim at stealing static passwords.
Convenience: Authenticator apps offer a convenient and user-friendly method of implementing 2FA, eliminating the need to rely on SMS-based authentication methods that may be vulnerable to SIM swapping attacks.
Authenticator apps and Time-based One-Time Passwords (TOTP) play a crucial role in safeguarding online accounts against unauthorized access and cyber threats. By incorporating 2FA with authenticator apps into their security protocols, individuals and organizations can significantly enhance their digital security posture in an increasingly interconnected world.
The protocol (otpauth) signals that an authenticator app should open this URL (DOMAIN).
the type (totp)
a label (USERNAME) that is a colon-separated combination of issuer and username
a secret (SECRET)
the issuer
The key element for logging in and automating the TOTP process is the supplied secret.
However, what’s the utilization method for this secret?
When you scan the QR code with an authenticator app, it combines the secret with the current time to create a unique password. The app then stores the second-factor secret, shows the issuer and username, and generates a new passcode every 30 seconds (though this time frame can be changed).That’s the gist of it!
You can then employ the passcode as a secondary login factor, providing assurance to services that it is indeed you are accessing your account.
Automating Login with Playwright for 2FA-Secured Websites
Automating the login process for websites secured with two-factor authentication (2FA) can streamline testing and administrative tasks. Playwright, a powerful automation library, provides the tools necessary to automate interactions with web pages, including those requiring 2FA.
Prerequisites:
Install Node.js: Make sure Node.js is installed on your system. You can download it from nodejs.org.
Set Up Playwright: Install Playwright using npm, the Node.js package manager, by running the following command in your terminal:
// Navigate to login page
await page.goto('https://example.com/login');
Enter Username and Password:
// Enter username and password
await page.fill('#username', 'your_username');
await page.fill('#password', 'your_password');
Click on the Login Button:
// Click on the login button
await page.click('#loginButton');
Handle 2FA Authentication:
Playwright supports interacting with elements on the page to handle 2FA. You can wait for the 2FA input field to appear and then fill it with the code.
The new OTPAuth.TOTP() syntax indicates that an instance of the TOTP class from the OTPAuth library is being created.
This instance is configured with various parameters such as issuer, label, algorithm, digits, period, and secret, which are used to generate and validate one-time passwords for authentication purposes.
In essence, new OTPAuth.TOTP() initializes a new TOTP (Time-based One-Time Password) object, allowing the application to generate OTPs for user authentication.
totp.generate() is a method call on the totp object. This method is provided by the OTPAuth library and is used to generate a one-time password (OTP) based on the TOTP algorithm.
The generate() method computes the current OTP value based on the TOTP parameters configured earlier, such as the secret key, time period, and algorithm. This OTP is typically used for user authentication purposes.
Once token holds the generated OTP, it can be used in the subsequent lines of code for filling an authentication code input field and submitting it for authentication.
Here’s the final code.
import * as OTPAuth from 'otpauth';
export class LoginPage {
readonly page: Page;
private readonly loginButton: Locator;
private readonly userNameInput: Locator;
private readonly passwordInput: Locator;
private readonly emailDisplay: Locator;
private userEmail: any;
private readonly authCode: Locator;
private readonly submitAuthCode: Locator;
constructor(page: Page) {
this.page = page;
this.loginButton = page.getByTestId(AppUniqueId.login_submitButton);
this.userNameInput = page.getByTestId(AppUniqueId.login_username);
this.passwordInput = page.getByTestId(AppUniqueId.login_password);
this.emailDisplay = page.getByTestId(AppUniqueId.personalDetails_email);
this.authCode = page.locator('#root > div > div > section > main > div > div > div > input');
this.submitAuthCode = page.locator('#root > div > div > section > main > div > div > button');
}
async waitFor(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async loginUserUI(childUser: User) {
let totp = new OTPAuth.TOTP({
issuer: "ISSUER",
label: "LABLE",
algorithm: "SHA1",
digits: 6,
period: 30,
secret: "XXXXXXXXXX”
});
await this.userNameInput.fill(await childUser.username);
await this.passwordInput.fill(await childUser.password);
await this.loginButton.click();
try{
let token = totp.generate()
await this.authCode.fill(token, { timeout: 5000});
await this.submitAuthCode.click()
}catch(err)
{
}
}
async verifyLoginUserEmail(childUser: User) {
this.userEmail = childUser.username;
try{
await this.page.locator("div[class='col-sm-12 d-flex impersonation-bar'] a").click()
}catch(err)
{
}
}
}
Conclusion:
Automating login for 2FA-secured websites using Playwright can enhance efficiency and productivity in various scenarios, from testing to administrative tasks. By following the steps outlined above, you can create robust automation scripts tailored to your specific requirements. https://github.com/apurvakolse/playwright-typescript-totp
Feel free to customize and expand upon these steps to suit your needs and the specific requirements of the website you’re working with.
Disclaimer: Ensure that you have the necessary permissions to automate interactions with websites, and use this knowledge responsibly and ethically.
Apurva is a Test Engineer, with 3+ years of experience in Manual and automation testing. Having hands-on experience in testing Web as well as Mobile applications in Selenium and Playwright BDD with Java. And loves to explore and learn new tools and technologies.
In this blog, I’m going to share with you how to create executable Jar File for automation framework designed with Cucumber, Java, Selenium and Maven.
What is the executable jar file?
The executable jar file to execute Cucumber Scenarios includes all build structures files of the framework along with packages, and dependencies. That works as an execution of the test cases.
Why so we need a jar file?
We have a framework that contains numerous test cases.Instead of giving you the code, we’ll give you a tool that can run these tests and make reports customized for different needs like quick checks and in-depth checks. Sometimes, the client doesn’t want to see or understand how the framework works. They simply want the final reports like Allure, HTML, or PDF reports which help them assess the quality of the product. The client doesn’t require an IDE like IntelliJ or Eclipse, for instance. They just need a user interface where they can click a button to generate the reports. This approach helps reduce their complexity. In such scenarios, we need a JAR file. This JAR file facilitates the triggering of test cases according to specific Cucumber tags and generates the necessary reports.
Technology used for this project (Executable jar file)
In the software testing world, the commonly used tool is selenium. Most of the creators used this stable and compatible tool for Automation.
Selenium: The software testing community has had faith in Selenium since 2004, as it’s been a reliable tool for testing. Most of us are familiar with selenium. If you are a beginner, please check out here.
Maven: The maven is a build management tool. Maven builds and manages Java-based projects. Maven provides an easy way to share the JARs across several projects. If you want to know more about Maven please check out here
Java: We are using the programming language Java for this project.
Cucumber: Cucumber supports behavior-driven development as a tool.
Prerequisites for the project (Executable jar file)
The following tools might have been installed on your system to executable jar file.
Java: Please check, is jdk installed on your system? If you cannot find the Java version on your system, please check out here to install Java.
Maven: Please check, is maven installed on your system? If you could not find the maven version on your system, please check out here to install maven.
Cucumber: When you create the maven project, you need to add cucumber plugins in the project setting window. If you wish to explore the cucumber in detail, here is the link Link you can refer to.
Framework Overview of Bdd Cucumber project
I am assuming you know the basic Bdd cucumber project architecture. For the creation of a jar, we need to modify the folder structure. Here I am highlighting the required files and key factors.
Let’s see the framework folder structure.
When we created the new project for the executable jar file, we could see the simple folder structure provided by Maven.
SRC Folder: The SRC folder is the parent folder of a project that will include the main and test folders. For the QA environment, normally we are using the test folder. The main folder is used for the development environment. The created jar contains all files inside the src folder.
Test Folder: Inside the test folder, Java and resources folders are available.
Java Folder: This folder contains the Java classes where the actual code is present.
Resources Folder: The Resources folder contains the resources file, test data file, and document files.
Pom.xml: In this file, we are managing the dependencies and plugins that are required for automation.
Structure of the Test Folder
The test folder design is the base of the executable jar file creation for the cucumber framework. Inside the java folder, we have to create a directory (org.BDD). In this directory, we need to create a subdirectory on the basis of code design Let’s see the subdirectory
1. Core
The core folder contains a subfolder. In the core folder, we set the standard code like…
Hooks: This Java class contains the basic before and after functions. These functions are set for the browser initialization and termination. Also, we can set the before and after methods, steps, and scenarios as per project requirements.
package org.CBDD.core;
import io.cucumber.java.After;
import io.cucumber.java.Before;
import io.cucumber.java.Scenario;
import org.CBDD.utilities.WebUtil;
public class Hooks extends TestContext {
@Before
public void beforeScenario(Scenario scenario) {
driver = WebUtil.initWebDriver();
}
@After
public void afterScenario() {
WebUtil.tearDown();
}
}
Main: While executing Java programs, by default, the JDK calls the Main functions. For the execution of a jar, we need the java command, hence we need to define the main class in our framework.
package org.CBDD.core;
public class Main {
public static void main(String[] args) throws Throwable {
String[] arguments = {};
io.cucumber.core.cli.Main.run(arguments);
}
}
TestContext: The TestContext Java class is used to define instances of classes and declare global variables. Here, Java classes extend the TestContext class and inherit the properties and values of the content.
package org.CBDD.core;
import org.openqa.selenium.WebDriver;
import org.CBDD.pages.CalculatorPage;
public class TestContext {
public static WebDriver driver;
public static CalculatorPage calculatorPage;
}
TestRunner: The Java class contains the @CucumberOptions properties. In the TestRunner class, we define the glue between the step definitions and feature files. In the case of BDD, this TestRunner class plays an important role.
package org.CBDD.core;
import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;
import org.testng.annotations.DataProvider;
@CucumberOptions(features = "classpath:Features",
glue = {"org.CBDD"})
public class TestRunner extends AbstractTestNGCucumberTests {
@DataProvider
@Override
public Object[][] scenarios() {
return super.scenarios();
}
}
2. Steps:
The Steps folder contains the Java classes for step definitions. In this folder, we need to specify the path in the glue option of the @CucumberOptions annotation so that the feature files can detect the step definitions during execution. If the glue is not properly mentioned, an ‘undefined step’ error will occur.
Inside the Steps folder, each Java class contains the implementations of the steps as defined in the feature files.
package org.CBDD.steps;
import org.CBDD.core.TestContext;
import io.cucumber.java.en.And;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import org.testng.Assert;
import org.CBDD.pages.CalculatorPage;
import java.io.IOException;
public class CalculatorSteps extends TestContext {
public CalculatorSteps() {
calculatorPage = new CalculatorPage();
}
@Given("I am on Calculator page")
public void iAmOnCalculatorPage() throws IOException {
calculatorPage.iAmOnCalculatorPage();
}
@When("I enter number {int}")
public void iEnterNumber(int number) {
calculatorPage.iEnterNumber(number);
}
@And("I click on operator {string}")
public void iClickOnOperator(String operator) {
calculatorPage.iClickOnOperator(operator);
}
@Then("I verify the result as {int}")
public void iVerifyTheResultAs(int expectedResult) {
String actualResult = calculatorPage.iVerifyTheResultAs();
Assert.assertEquals(actualResult, String.valueOf(expectedResult));
}
}
3. Pages:
The Pages folder contains the page classes that house the actual code. The page functions are called in the step class.
package org.CBDD.pages;
import org.CBDD.core.TestContext;
import org.openqa.selenium.By;
import org.CBDD.utilities.ConfigUtil;
import java.io.IOException;
public class CalculatorPage extends TestContext {
public void iAmOnCalculatorPage() throws IOException {
driver.get(ConfigUtil.getPropertyValue("base_url"));
}
public void iEnterNumber(int number) {
driver.findElement(By.xpath("//span[@onclick='r(" + number + ")']")).click();
}
public void iClickOnOperator(String operator) {
driver.findElement(By.xpath("//span[@onclick=\"r('" + operator + "')\"]")).click();
}
public String iVerifyTheResultAs() {
driver.findElement(By.xpath("//span[@onclick=\"r('=')\"]")).click();
return driver.findElement(By.xpath("//div[@id='sciOutPut']")).getText().trim();
}
}
4. Utilities:
The Utilities folder contains utilities to reduce the repetition of code. It includes the WebUtil class, which contains functions for browser initialization and termination.
package org.CBDD.utilities;
import io.github.bonigarcia.wdm.WebDriverManager;
import org.CBDD.core.TestContext;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class WebUtil extends TestContext {
public static WebDriver initWebDriver() {
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
driver.manage().window().maximize();
return driver;
}
public static void tearDown() {
driver.quit();
}
}
5. Resources:
Normally, this folder is used to store resources such as test data, properties, and configuration files. In this case, we need to declare the feature files inside the resources folder because the created target folder contains a non-editable feature folder. This setup ensures that feature files are correctly packaged and accessible during the build process.
Features: Features contain the feature files. We need to provide the path of this folder in glue. Here we provide the path “classpath:Features” beecause, the jar does not contain the absolute path. @cucumberOptions(features = “classpath:Features”, glue = {“org.CSDD”}) In the feature file, we use the Gherkin language to write test cases.
Feature: Verify Calculator Operations
@addsub
Scenario Outline: Verify addition and subtraction of two numbers
Given I am on Calculator page
When I enter number <number>
And I click on operator '<operator>'
And I enter number <number1>
Then I verify the result as <expectedResult>
Examples:
| number | operator | number1 | expectedResult |
| 5 | + | 2 | 7 |
| 9 | - | 3 | 6 |
@muldiv
Scenario Outline: Verify multiplication and division of two numbers
Given I am on Calculator page
When I enter number <number>
And I click on operator '<operator>'
And I enter number <number1>
Then I verify the result as <expectedResult>
Examples:
| number | operator | number1 | expectedResult |
| 6 | * | 4 | 24 |
| 2 | / | 2 | 1 |
Cucumber.properties: This properties file is used to set the Cucumber configuration. Normally during the execution, this file is detected by Cucumber automatically and the configuration is implemented. The same configuration can be set in the TestRunner class. In the case of CI/CD execution or jar execution, the priority goes to the cucumber.properties file rather than the TestRunner class. Hence, we need to implement the same configuration in both the TestRunner class and the cucumber.properties file.
cucumber.publish.enabled:true
CUCUMBER_PUBLISH_TOKEN:0b5c7164-ab9e-43ed-b6ba-da66c5e07c02
cucumber.features= Features
cucumber.glue=org.CBDD.core,org.CBDD.steps
Manifest file: This file is the most important file for executing the jar file. The manifest file by default houses the META-INF folder. This file contains information about the files packaged in a JAR file. This manifest file specifies the Main class and the jar packages that are available in the External Libraries folder. The purpose of having a manifest file is to specify the main class, which is easily detected by the JAR during execution. Without a manifest file, the JAR cannot identify the main class; hence, the JDK is confused about selecting the execution entry point.
How to add Manifest file in project folder structure
For adding the manifest file to your project, there are two ways.
Add the manifest file from the project settings.
Assuming you are using the IntelliJ IDEA editor, follow the procedure below:
Click on the File menu and select Project Settings.
Click on the file menu and select the project setting
Select the artifacts from the project structure screen
Click on ‘+’ icon, select the jar option -> form module with dependencies
Select the main class -> select the checkbox of ‘copy to the output directory and link via manifest’ -> enter the directory for META-INF/MANIFEST.MF as ‘project directory + src\test\resources’
Click on the Apply button and the OK button
You can see the manifest file stored in your resources folder.
Add the manifest file with the org.apache.maven.plugins
Here, we need to add the Maven plugin to the pom.xml file. In this plugin, we need to mention the path where the manifest file is stored and the Main class package.
<build>
<plugins>
<plugins>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version> <!-- Use the latest available version -->
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>src/test/resources/</classpathPrefix>
<mainClass>org.CBDD.core.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugins>
</plugins>
</build>
6. POM.xml File
Maven has the pom.xml file that contains information about the project and configuration details. It contains the default architecture for most projects.
Project dependencies configuration is specified in the pom.xml file as per requirement. We have added the plugins provided by Maven as per our project needs and configuration.
Let’s see some required plugins for jar creation.
Maven-jar-plugin: This plugin provides the capability to build the jar. It helps to create a jar for test classes of the project. In this plugin, we need to mention the manifest file path that will decide the main class of the jar file. We can check the latest version of this plugin on the Maven repository. In case, you are having a problem setting the plugin, you can go with the maven-jar-plugin dependencies.
Maven-dependency-plugin: When we create the jar, we will see it in the target folder. The jar file contains the manifest file and packages inside the jar directory or target folder. Hence, this plugin comes into the picture. The plugin copies all dependencies or packages from the pom.xml file and stores them in the jar directory folder (target folder). During execution, the jar requires these dependencies/packages/jars.
Maven-resources-plugin: The resources folder contains the test data, properties, and document files. Without this plugin, when we create the jar, the jar doesn’t contain the files from the resources folder. In case we need to provide these files externally to the jar. So, to avoid this painful process, we can use this plugin. This plugin works by copying all files from the resource folder into the jar files. After the creation of the jar file, we can check the availability of this file in the command prompt with this command: “Jar tf file.jar”
As you have followed the above process and configuration, we can proceed with jar creation. We can create the jar in two ways.
Create a jar with the help of the command: ‘mvn package’
In your project directory, open the terminal. Maven has a command to create a jar, which is ‘mvn package’. When you execute this command, it starts the process of creating the JAR and runs your test cases. After the completion of this process, you will find the jar file in the target folder.
Create the jar file with maven lifecycle steps
In your IntelliJ IDEA, there is an E-Maven tab. This tab includes the Lifecycle sub-tab.
Follow this process:
Clicks on the lifecycle tab and follow below diagram.
Execution of jar file
Once you successfully create the JAR along with the dependencies in the target folder, you can use some commands related to the JAR file.
Check the directories in jar file
To check the directories included in a jar file, you can use the command ‘jar tf filename.jar’. This command will list all the files and directories contained within the jar file.
Output:
Run the jar file
Normally, when we run a jar file, the jar file starts with the main class. Whatever configurations the main class includes, those files will execute. The command to run a jar file is: Java jar jarFileName.jar
Output:
Run the specific test case from jar
Normally, we execute the smoke or regression test cases. We differentiate the test cases by tag name. In this project, we have two scenarios with the tags “@addsub” and “@muldiv.”
Based on the tags, we can select the test cases for execution. Open the terminal and change the directory to the target folder. The command for execution is as follows: java -cp jarFileName.jar io.cucumber.core.Main featurefileName –tags “@tagname”
The creation of a jar file for a Cucumber Maven framework, as described, represents a strategic approach that offers flexibility in executing test cases directly from the jar file. This JAR file helps minimize issues related to redundant code and ensures stable and customized execution.
In conclusion, creating a jar with Selenium, Java, and BDD using Cucumber helps deliver high-quality software. By following best practices like designing a robust framework architecture, leveraging Maven plugins, and configuring the cucumber.properties file, we can generate an executable JAR file for effective automation testing.This enhances the stability of the test cases and reduces the failure rate.
Source Code:
Wish to take a look at the source code? You can attain a clearer and more straightforward understanding by visiting the repository at the following URL, where you’ll find a comprehensive guide that outlines the steps to follow. https://github.com/spurqlabs/JAR-File-Creation-
Click here to read a more blogs to increase your software testing skills.
An SDET with hands-on experience in the life science domain, including manual testing, functional testing, Jira, defect reporting, web application, and desktop
application testing. I also have extensive experience in web and desktop automation using Selenium, WebDriver, WinAppDriver, Playwright, Cypress, Java, JavaScript, Cucumber, maven, POM, Xray, and building frameworks.
Desktop application test automation can be a tedious task as it’s hard to locate the elements and interact with those elements. There are plenty of tools available for automating desktop applications. Winium is one of those tools which is a selenium-based tool. So for those who don’t have an idea about Selenium, Selenium is a web application test automation tool that supports almost all programming languages. (Wish to learn more about selenium? Check out the link here) If you are familiar with the Selenium tool then it’s going to be easy for you to understand the workings of the Winium tool as most of the methods are common and if you are not familiar with Selenium no worries, I have got you covered.
Coming back to our topic, In this blog we will see how we can create a robust test automation framework for automating desktop applications using Winium a desktop application automation tool, Java as a programming language, Maven, as a dependency management tool, Cucumber as a BDD (Behavior Driven Development) tool. We are going to build a test automation framework from scratch. Even if you don’t have any idea on how to create a framework no worries.
Before we start building the framework let’s complete the environment set-up. So for this, we will have to install some tools. Below I am sharing the URLs of the tools we are using just in case if you want to know more about these tools then you can visit these official web pages.
Once the download is completed the next step is setting up the path in the environment variables. Check the below screenshots to set up the path in your system environment variables
Once you are done with the above steps then you should see the below information in the command prompt.
Maven Set-up :
Once you are done with Java Installation and set up the next step is to do the installation and set up the maven.
Not only that there are other desktop application element inspection tools.
Once you are done with the above steps then we can start building the automation framework.
Implementing BDD with Cucumber for Desktop Automation:
The BDD (Behavior-Driven-Development) is a software development approach that focuses on collaboration among stakeholders, including developers, QA engineers, and business analysts. The reason behind this is that in the BDD approach, we use natural language specifications to describe software behaviour from the end user’s perspective. I believe this helps in creating a shared understanding of requirements and promotes effective communication throughout the development lifecycle. Let’s see this in detail,
Feature File Creation :
Feature files are the main component of the BDD cucumber framework we can even say they are the heart of this cucumber framework.
These files are written using gherkin language which describes the high-level functionalities of the application.
Cucumber is a widely used BDD tool as it allows us to write test cases (scenarios) in plain tests using the Gherkin syntax.
This is because Gherkin uses keywords like, Given, When, And, and Then to structure scenarios, making it easy to read and understand by both technical and non-technical stakeholders.
Here is the one scenario that I have created for this framework.
@winiumApp
Feature: To verify the draw functionality of AutoCAD software
As a User I want to launch the application
and validate that I can access the different functionalities of the application.
@smoke
Scenario: Verify user can launch and open the new document using microsoft word application
Given User launches the microsoft word application
When User verifies the landing screen is visible with "Recent" opened document list
And User clicks on "Blank document" option to add blank document
Then User verifies that "Page 1 content" a new page for opened blank page is visible
Step Definition File Creation :
Yes, that’s correct. Step definition files contain code that maps the steps in the feature file to automation code.
These files are written using the programming language used in the automation framework, in this case, Java.
The step definitions are responsible for interacting with the elements of the application and performing actions on them such as clicking, entering text, etc.
They also contain assertions to check if the expected behaviour is observed in the application.
package com.SpurCumber.Steps;
import com.SpurCumber.Pages.DemoWiniumAppPage;
import com.SpurCumber.Utils.ScreenshotHelper;
import com.SpurCumber.Utils.TestContext;
import io.cucumber.java.en.And;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import org.testng.Assert;
public class DemoWiniumAppSteps extends TestContext {
private final DemoWiniumAppPage demoWiniumAppPage;
public DemoWiniumAppSteps() {
demoWiniumAppPage = new DemoWiniumAppPage(winiumdriver);
}
@Given("User launches the microsoft word application")
public void userLaunchesTheMicrosoftWordApplication() {
scenario.log("The application is launched successfully!");
ScreenshotHelper.takeWebScreenshotBase64(winiumdriver);
ScreenshotHelper.captureScreenshotAllure(winiumdriver, "User launches the microsoft word application");
}
@When("User verifies the landing screen is visible with {string} opened document list")
public void userVerifiesTheLandingScreenIsVisible(String arg0) throws InterruptedException {
Assert.assertTrue(demoWiniumAppPage.verifyScreen(arg0));
ScreenshotHelper.takeWebScreenshotBase64(winiumdriver);
ScreenshotHelper.captureScreenshotAllure(winiumdriver, "User verifies the landing screen is visible with "+arg0+" opened document list");
}
@And("User clicks on {string} option to add blank document")
public void userClicksOnOptionToAddBlankDocument(String arg0) throws InterruptedException {
demoWiniumAppPage.clickBtnByName(arg0);
ScreenshotHelper.takeWebScreenshotBase64(winiumdriver);
ScreenshotHelper.captureScreenshotAllure(winiumdriver, "User clicks on "+arg0+" option to add blank document");
}
@Then("User verifies that {string} a new page for opened blank page is visible")
public void userVerifiesThatANewPageForOpenedBlankPageIsVisible(String arg0) throws InterruptedException {
Assert.assertTrue(demoWiniumAppPage.verifyScreen(arg0));
ScreenshotHelper.takeWebScreenshotBase64(winiumdriver);
ScreenshotHelper.captureScreenshotAllure(winiumdriver, "User verifies that "+arg0+" a new page for opened blank page is visible");
}
}
Hooks File Creation :
In Cucumber, hooks are methods annotated with @Before and @After that run before and after each scenario.
To ensure consistency between test environments, these hooks are used for setting up and taking down tests.
The application can be initialized before and cleaned up after each scenario using hooks, for example.
Implementing Page Object Model (POM) for Desktop Automation:
The Page Object Model (POM) is a design pattern that assists in building automation frameworks that are scalable and maintainable. In POM, we create individual page classes for each application page or component, which encapsulates the interactions and elements associated with that particular page. This approach improves code readability, reduces code duplication, and enhances test maintenance.
package com.SpurCumber.Pages;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.winium.WiniumDriver;
public class DemoWiniumAppPage {
private final WiniumDriver winiumdriver;
public DemoWiniumAppPage(WiniumDriver _winiumdriver) {
this.winiumdriver = _winiumdriver;
}
public Boolean verifyScreen(String locator) throws InterruptedException {
WebElement Screen = winiumdriver.findElementByName(locator);
return Screen.isDisplayed();
}
public void clickBtnByName(String locator) throws InterruptedException {
WebElement element = winiumdriver.findElementByName(locator);
Thread.sleep(3000);
element.click();
}
}
Creating Utility Files to Support Framework:
In a test automation framework, utility files provide reusable functionalities, configurations, and helper methods to streamline the development, execution, and maintenance of test scripts. As a result, they enhance the efficiency, scalability, and maintainability of the automation framework. Listed below are a few common utility files, along with their functions:
Winium Util File :
This utility file handles the launch and termination processes of the desktop application, as well as the Winium driver
When we use Winium as a desktop application automation tool we have to start the server. (Winium Driver).
Either we can do this manually before starting the execution of the test case or we can do this through automation as well.
In the below utility file there are methods created for launching the desktop application and Winium driver (server).
This common util file reads or retrieves the values and files present in a particular folder (referenced here as the resource folder).
This file can further serve as a basis for developing additional common methods usable throughout the framework.
package com.SpurCumber.Utils;
import java.io.File;
import java.nio.file.Paths;
public class CommonUtil {
public static String getResourceDirPath(String parameter) {
String assemblyLocation = System.getProperty("user.dir");
String path = Paths.get(assemblyLocation+"/src/test/resources/"+parameter).toString();
return new File(path).getAbsolutePath();
}
}
Test Runner File :
The TestRunner class executes Cucumber tests with specified configuration settings, including the location of feature files, step definitions package, inclusion tags, and report generation plugins.
The seamless integration of Cucumber tests into TestNG makes testing and reporting easy.
Once we have defined the test scenarios, we will use Maven commands to execute them. Maven is a robust tool that manages project dependencies and automates the build process. With Maven, we can run automated tests with ease and ensure a smooth and efficient testing process.
Configuring Maven POM File(Pom.xml):
In the project’s Maven Project Object Model (POM) file, we define the necessary configurations for test execution.
This includes specifying the test runner class, defining the location of feature files and step definitions, setting up plugins for generating test reports, and configuring any additional dependencies required for testing.
Once you configure the automated tests in the Maven POM file, you can run them using Maven commands from the terminal or command prompt. Common Maven commands used for test execution include:
mvn test – This command runs all the tests from the project.
mvn clean test – This command first cleans the project (removes the target directory) and then runs the tests.
mvn test “-Dcucumber.filter.tags=@tagName” – This command runs tests with specific Cucumber tags.
Generating Cucumber Reports:
Cucumber provides built-in support for generating comprehensive test reports. By configuring plugins in our automation framework, we can generate detailed reports that showcase the test results, including passed, failed, and pending scenarios. These reports offer valuable insights into the test execution, helping us identify issues, track progress, and make data-driven decisions for test improvements.
Conclusion:
Automating desktop applications with Winium, Java, and Behavior-Driven Development (BDD) using Cucumber is a strategic approach that offers numerous benefits to software development and testing teams. By combining these technologies and methodologies, we create a robust automation framework that enhances software quality, reduces manual efforts, and promotes collaboration across teams.
In conclusion, automating desktop applications with Winium, Java, and BDD using Cucumber empowers teams to deliver high-quality software efficiently. By leveraging the strengths of each technology and following best practices such as the Page Object Model and Maven integration, we create a solid foundation for successful test automation that aligns with business goals and enhances overall product quality.
Source Code:
You can access the complete source code of the created automation framework for desktop applications using Winium, Java, and BDD with Cucumber on GitHub at https://github.com/spurqlabs/Desktop-App-Winium-Java-Cucumber The framework includes feature files, step definitions, page classes following the Page Object Model, Maven dependencies, and configuration files for generating Cucumber reports. Feel free to explore, fork, and contribute to enhance the framework further.
An SDET Engineer with hands-on experience in manual, automation, API, Performance, and Security Testing. The technologies I have worked on include Selenium, Playwright, Cypress, SpecFlow, Cucumber, JMeter, K6, OWASP ZAP, Appium, Postman, Maven, Behave, Pytest, BrowserStack, SQL, GitHub, Java, JavaScript, Python, C#, HTML, css. Also, I have hands-on experience in CI/CD the technologies I have used for CI/CD include Azure DevOps, AWS, and Github. Apart from this, I like to write blogs and explore new technologies.