Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 98 additions & 72 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,98 +1,124 @@
# LinkedIn Automation Testing Project
## 📌 Overview

## E2E Test Automation Framework
Simulates a real user journey on LinkedIn — from login, navigating to search, selecting recruiters, composing messages, and logging out.
It doesn’t just test isolated units; instead, it validates the entire workflow across multiple pages and components.

The framework also integrates with Zephyr for Jira for test case management, and is designed to run locally as well as in CI/CD pipelines (GitHub Actions, Jenkins, Docker).

## 🛠️ Tech Stack

Playwright (E2E browser automation)

TypeScript (strong typing and maintainability)

ExcelJS / XLSX (data-driven tests using recruiter names)

Node.js & npm (dependency management)

Dotenv (environment variables for credentials & config)

Zephyr Reporter (test management integration with Jira)

Allure Reports (visual test execution reports)

Docker & Jenkins (CI/CD pipeline support)

## Acknowledgements
Swaroop Landge https://www.linkedin.com/in/swaroop-landge-9a5b9111/ for continuous support, direction, and encouragement in shaping my journey into QA Automation.

## 🧩 Page Object Model (POM)

This project uses the Page Object Model (POM) design pattern for clean, reusable, and maintainable test automation. Each page has its own class with dedicated methods.

basePage.ts → Core utilities (navigation, waits, common actions)

loginPage.ts → Handles login (username, password, submit)

linkedInSearchPage.ts → Manages recruiter search

composeMessage.ts → Automates recruiter message composition
## 📌 Overview

logoutPage.ts → Handles logout flow
This project is an **End-to-End (E2E) Test Automation Framework** designed to simulate a real user journey on LinkedIn. It automates critical workflows such as logging in, searching for recruiters, composing personalized messages, and logging out.

readRecruiterNames.ts → Reads recruiter data from Excel (data-driven tests)
The framework goes beyond isolated unit tests by validating the entire workflow across multiple pages and components. It integrates with **Zephyr for Jira** for test case management and is built to run both locally and in CI/CD pipelines (GitHub Actions, Jenkins, Docker).

## flowchart TD
A[Login Page] --> B[LinkedIn Search Page]
B --> C[Compose Message Page]
C --> D[Logout Page]
E[Excel Data] --> B
## 🚀 Features

- **E2E Browser Automation**: Uses **Playwright** for reliable and fast browser interactions.
- **Page Object Model (POM)**: Implements POM design patterns for maintainable and scalable code.
- **Data-Driven Testing**: Reads recruiter names from Excel files (`.xlsx`) to dynamically generate test cases.
- **TypeScript**: Written in TypeScript for strong typing and better developer tooling.
- **Environment Management**: Uses `.env` files for secure handling of credentials and configuration.
- **Robust Reporting**: Integrates **Allure Reports** for visual execution results and **Zephyr** for Jira test management.
- **Email Notifications**: Automatically emails execution logs and reports upon test completion.
- **CI/CD Ready**: Configured for Docker and Jenkins integration.

⚙️ Setup & Installation
1. Clone Repository
git clone https://github.com/sameermanzur/Linkedin-Automation-Testing-Project/tree/End-to-End-Flow
cd LinkedIn-Automation-Project
## 🛠️ Tech Stack

2. Install Dependencies
- **[Playwright](https://playwright.dev/)**: E2E testing framework.
- **[TypeScript](https://www.typescriptlang.org/)**: Programming language.
- **[Node.js](https://nodejs.org/)**: Runtime environment.
- **[ExcelJS](https://github.com/exceljs/exceljs) / [XLSX](https://docs.sheetjs.com/)**: For reading Excel data.
- **[Dotenv](https://github.com/motdotla/dotenv)**: Environment variable management.
- **[Nodemailer](https://nodemailer.com/)**: For sending email reports.
- **[Allure](https://allurereport.org/)**: Reporting tool.

## 📂 Project Structure

```
├── data/
│ └── recruiterList.xlsx # Data file containing recruiter names
├── e2e/
│ └── example.spec.ts # Sample Playwright test
├── tests/
│ ├── pages/ # Page Object Models and Utilities
│ │ ├── basePage.ts # Base class for all pages
│ │ ├── loginPage.ts # Login page interactions
│ │ ├── linkedInSearchPage.ts # Search functionality
│ │ ├── composeMessage.ts # Message composition logic
│ │ ├── logoutPage.ts # Logout interactions
│ │ ├── readRecruiterNames.ts # Excel reading utility
│ │ ├── logAndReport.ts # Email reporting utility
│ │ ├── hooks.ts # Test hooks (setup/teardown)
│ │ └── globalTearDown.ts # Global cleanup scripts
│ ├── login.spec.ts # Login test suite
│ ├── userSendsMessage.spec.ts # Main E2E workflow test
│ └── seed.spec.ts # Data seeding placeholder
├── playwright.config.ts # Playwright configuration
├── package.json # Project dependencies and scripts
└── README.md # Project documentation
```

## ⚙️ Setup & Installation

### 1. Clone the Repository
```bash
git clone https://github.com/sameermanzur/Linkedin-Automation-Testing-Project.git
cd Linkedin-Automation-Testing-Project
```

### 2. Install Dependencies
```bash
npm install
```

3. Configure Environment

Create a .env file:
### 3. Configure Environment Variables
Create a `.env` file in the root directory and add the following variables:

```env
BASE_URL=https://www.linkedin.com
USERNAME=your_email@example.com
PASSWORD=your_password
LINKEDIN_USERNAME=your_email@example.com
LINKEDIN_PASSWORD=your_password
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
GOOGLE_REFRESH_TOKEN=your_google_refresh_token
GOOGLE_USER_EMAIL=your_email_for_sending_reports
REPORT_RECIPIENT=recipient_email@example.com
ZEPHYR_TOKEN=your_zephyr_api_key
```

4. Prepare Test Data
### 4. Prepare Test Data
Ensure `data/recruiterList.xlsx` exists and contains a list of names. The file should have headers like `First Name`, `Last Name`, or `Name`.

Update ./data/recruiterNames.xlsx with recruiter names in FirstName / LastName / Name format.
## ▶️ Running Tests

▶️ Running Tests
Local Execution
### Run All Tests
```bash
npx playwright test
```

Run Specific Test
npx playwright test tests/verifyE2EuserFlow.spec.ts --headed

Clear Cache & Cookies (best practice hooks)
### Run Specific Test File
```bash
npx playwright test tests/userSendsMessage.spec.ts
```

Hooks automatically clear session storage, cookies, and cache before each test run.
### Run in Headed Mode (Visible Browser)
```bash
npx playwright test --headed
```

🧩 Key Features
### Generate Allure Report
```bash
npx allure generate ./allure-results --clean
npx allure open
```

✅ Data-driven testing using Excel recruiter list
## 🧩 Page Object Model (POM) Details

✅ Page Object Model (POM) for maintainability
- **BasePage**: Contains common methods like `b_navigateTo`, `b_clickElement`, and `b_fillField`.
- **LoginPage**: Encapsulates login logic (`enterUserName`, `enterPassword`, `login`).
- **LinkedInSearchPage**: Handles navigating to the feed and searching for recruiters.
- **ComposeMessagePage**: Manages opening message dialogs, generating personalized text, and sending messages.
- **LogoutPage**: Handles the logout process to ensure a clean state.

✅ Environment-driven setup with .env
## 🤝 Acknowledgements

✅ Clear cache/cookies hooks for clean sessions
Special thanks to [Swaroop Landge](https://www.linkedin.com/in/swaroop-landge-9a5b9111/) for his continuous support and mentorship in QA Automation.

✅ Integration with Jira Zephyr for reporting
## 📄 License

✅ CI/CD ready (Docker + Jenkins + GitHub Actions)
This project is licensed under the ISC License.
9 changes: 9 additions & 0 deletions e2e/example.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import { test, expect } from '@playwright/test';

/**
* Test Case: has title
* Verifies that the Playwright homepage has the correct title.
*/
test('has title', async ({ page }) => {
await page.goto('https://playwright.dev/');

// Expect a title "to contain" a substring.
await expect(page).toHaveTitle(/Playwright/);
});

/**
* Test Case: get started link
* Verifies that the 'Get started' link on the Playwright homepage works correctly
* and navigates to the Installation page.
*/
test('get started link', async ({ page }) => {
await page.goto('https://playwright.dev/');

Expand Down
16 changes: 15 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 26 additions & 3 deletions tests/login.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,28 @@ import { test, expect } from '@playwright/test';
import { LoginPage } from './pages/loginPage'
import { sendReportEmail } from './pages/logAndReport';

/**
* Test Suite: Login Tests
* Contains tests related to the user login functionality.
*/
test.describe('Login Tests', () => {
/**
* Before each test, navigate to the base URL.
*/
test.beforeEach(async ({ page }) => {
const login = new LoginPage(page);
await login.b_navigateTo(process.env.BASE_URL!);
});

/**
* Test Case [T2]: Login with Valid credentials.
* Tagged as @smoke.
*
* Steps:
* 1. Perform login with valid username and password.
* 2. Verify that the URL contains "feed", indicating a successful login.
* 3. Trigger the email report (Note: This might be better placed in a global teardown).
*/
test('T2] Login with Valid credentials', {tag:'@smoke'}, async ({page }) => {
const login = new LoginPage(page);
await login.login(process.env.LINKEDIN_USERNAME!, process.env.LINKEDIN_PASSWORD!);
Expand All @@ -16,6 +32,16 @@ test.describe('Login Tests', () => {
await sendReportEmail();
});

/**
* Test Case [T3]: Session persistence after login.
*
* Steps:
* 1. Login with valid credentials.
* 2. Open a new tab (page) in the same context.
* 3. Navigate to the base URL in the new tab.
* 4. Verify that the user is still logged in (URL pattern check).
* 5. Reload the original page and verify persistence.
*/
test('[T3] Session persistence after login', async ({ page, context }) => {
const login = new LoginPage(page);
await login.login(process.env.LINKEDIN_USERNAME!, process.env.LINKEDIN_PASSWORD!);
Expand All @@ -28,6 +54,3 @@ test.describe('Login Tests', () => {
await expect(newPage).toHaveURL(/.*homepage/);
});
});



Loading