From d31d932ef4b9bac18fdb0322eea9d83833a738a9 Mon Sep 17 00:00:00 2001 From: Abhay Bharti Date: Tue, 6 Feb 2024 21:37:47 +0530 Subject: [PATCH] added --- README.md | 12 ++++++- playwright.config.ts | 2 +- src/helper/api/apiHelper.ts | 36 +++++++++++-------- src/tests/web/example/assertion.spec.ts | 46 ++++++++++++------------- src/tests/web/example/route.spec.ts | 32 ++++++++++++++++- src/utils/dataStore.js | 10 ++++++ 6 files changed, 97 insertions(+), 41 deletions(-) create mode 100644 src/utils/dataStore.js diff --git a/README.md b/README.md index a20291a..9f8dd72 100644 --- a/README.md +++ b/README.md @@ -18,10 +18,12 @@ _☝ If you liked the project, please give a ⭐ on [GitHub](https://github.com/ - Support Mobile automation with support for Android native, web and hybrid apps automation - Support iOS native, web and hybrid apps automation - Support execution of Web tests on Microsoft Azure (can scale on demand) -- Support API testing +- Support API testing (GET, POST, PUT, DELETE HTTP methods) +- Dynamic data handling using external JSON files - Support taking screenshots - Run functional test for load testing using Artillery - Support Serial and Parallel execution +- Environment configuration using .env files ## Tech Stack/Libraries Used @@ -36,6 +38,10 @@ _☝ If you liked the project, please give a ⭐ on [GitHub](https://github.com/ ## Getting Started +## Project Structure +- `apiHelper.ts` contains functions for making HTTP requests +- `utils` contains utility functions + ### Prerequisite - `nodejs`: Download and install Node JS from @@ -76,6 +82,10 @@ Playwright test generator generates tests and pick locator for you. It uses role To pick a locator, run the `codegen` command followed by URL, `npx playwright codegen https://opensource-demo.orangehrmlive.com/web/index.php/auth/login` +## Writing Tests + +- Create test files in `src/tests` folder + ## Sample Test ### Sample Web Test diff --git a/playwright.config.ts b/playwright.config.ts index 33701af..08df9f5 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -44,7 +44,7 @@ export default defineConfig({ // baseURL: 'http://127.0.0.1:3000', /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ - trace: "on-first-retry", + trace: "retain-on-failure", }, /* Configure projects for major browsers */ diff --git a/src/helper/api/apiHelper.ts b/src/helper/api/apiHelper.ts index 9dd916f..98ba3da 100644 --- a/src/helper/api/apiHelper.ts +++ b/src/helper/api/apiHelper.ts @@ -2,6 +2,7 @@ import { request, expect, APIResponse } from "@playwright/test"; import exp from "constants"; import { StringLiteral } from "typescript"; +const BASE_URL = "https://jsonplaceholder.typicode.com"; export class ApiHelper { private apiContext: any; @@ -12,7 +13,12 @@ export class ApiHelper { * credentials, request headers, and other configuration settings. */ constructor(apiContext: any) { - this.apiContext = apiContext.newContext(); + this.apiContext = apiContext.newContext({ + extraHTTPHeaders: { + Authorization: `Bearer 12345`, + "Content-Type": `application/json`, + }, + }); } /** @@ -59,8 +65,8 @@ export class ApiHelper { async invokeGetApi(endPoint: string, statusCode: number = 200) { let response; try { - console.log(`endPoint: , ${endPoint} `); - response = await this.apiContext.get(endPoint); + console.log(`Making GET request to endPoint: ${BASE_URL}${endPoint}`); + response = await this.apiContext.get(`${BASE_URL}${endPoint}`); expect(response.status()).toBe(statusCode); return await response.json(); } catch (error) { @@ -70,8 +76,10 @@ export class ApiHelper { async invokeDeleteApi(endPoint: string, statusCode: number = 200) { let response; try { - console.log(`endPoint: , ${endPoint} `); - response = await this.apiContext.delete(endPoint); + console.log( + `Making DELETE request to endPoint: ${BASE_URL}${endPoint}` + ); + response = await this.apiContext.delete(`${BASE_URL}${endPoint}`); expect(response.status()).toBe(statusCode); return await response.json(); } catch (error) { @@ -97,12 +105,11 @@ export class ApiHelper { ) { let response; try { - console.log(`endPoint: , ${endPoint} payload :${payload} `); - response = await this.apiContext.post(endPoint, { + console.log( + `Making POST request to endPoint: ${BASE_URL}${endPoint} payload :${payload} ` + ); + response = await this.apiContext.post(`${BASE_URL}${endPoint}`, { data: payload, - headers: { - "Content-Type": "application/json", - }, }); expect(response.status()).toBe(statusCode); return await response.json(); @@ -117,12 +124,11 @@ export class ApiHelper { ) { let response; try { - console.log(`endPoint: , ${endPoint} payload :${payload} `); - response = await this.apiContext.put(endPoint, { + console.log( + `Making PUT request to endPoint: ${BASE_URL}${endPoint} payload :${payload} ` + ); + response = await this.apiContext.put(`${BASE_URL}${endPoint}`, { data: payload, - headers: { - "Content-Type": "application/json", - }, }); expect(response.status()).toBe(statusCode); return await response.json(); diff --git a/src/tests/web/example/assertion.spec.ts b/src/tests/web/example/assertion.spec.ts index 8c2a985..a319eb0 100644 --- a/src/tests/web/example/assertion.spec.ts +++ b/src/tests/web/example/assertion.spec.ts @@ -49,34 +49,34 @@ test("Using playwright Non-Retrying Assertion", async ({ page }) => { await page.goto("https://www.google.com"); await expect(page).toHaveTitle("Google"); const value = ""; - expect(value).toBe(); //Value is the same - expect(value).toBeCloseTo(); // Number is approximately equal + expect(value).toBe("ABC"); //Value is the same + expect(value).toBeCloseTo(100); // Number is approximately equal expect(value).toBeDefined(); //Value is not undefined expect(value).toBeFalsy(); //Value is falsy, e.g. false, 0, null, etc. - expect(value).toBeGreaterThan(); // Number is more than - expect(value).toBeGreaterThanOrEqual(); // Number is more than or equal - expect(value).toBeInstanceOf(); //Object is an instance of a class - expect(value).toBeLessThan(); //Number is less than - expect(value).toBeLessThanOrEqual(); // Number is less than or equal + expect(value).toBeGreaterThan(5); // Number is more than + expect(value).toBeGreaterThanOrEqual(5); // Number is more than or equal + expect(value).toBeInstanceOf(Object); //Object is an instance of a class + expect(value).toBeLessThan(19); //Number is less than + expect(value).toBeLessThanOrEqual(19); // Number is less than or equal expect(value).toBeNaN(); //Value is NaN expect(value).toBeNull(); //Value is null expect(value).toBeTruthy(); // Value is truthy, i.e. not false, 0, null, etc. expect(value).toBeUndefined(); // Value is undefined - expect(value).toContain(); //String contains a substring - expect(value).toContain(); //Array or set contains an element - expect(value).toContainEqual(); //Array or set contains a similar element - expect(value).toEqual(); //Value is similar - deep equality and pattern matching - expect(value).toHaveLength(); //Array or string has length - expect(value).toHaveProperty(); // Object has a property - expect(value).toMatch(); //String matches a regular expression - expect(value).toMatchObject(); // Object contains specified properties - expect(value).toStrictEqual(); //Value is similar, including property types + expect(value).toContain("ABC"); //String contains a substring + expect(value).toContain("ABC"); //Array or set contains an element + expect(value).toContainEqual("ABC"); //Array or set contains a similar element + expect(value).toEqual(5); //Value is similar - deep equality and pattern matching + expect(value).toHaveLength(10); //Array or string has length + expect(value).toHaveProperty("name"); // Object has a property + expect(value).toMatch(/name/i); //String matches a regular expression + // expect(value).toMatchObject(); // Object contains specified properties + // expect(value).toStrictEqual(); //Value is similar, including property types expect(value).toThrow(); //Function throws an error - expect(value).any(); //Matches any instance of a class/primitive - expect(value).anything(); //Matches anything - expect(value).arrayContaining(); //Array contains specific elements - expect(value).closeTo(); //Number is approximately equal - expect(value).objectContaining(); // Object contains specific properties - expect(value).stringContaining(); //String contains a substring - expect(value).stringMatching(); //String matches a regular expression + // expect(value).any(); //Matches any instance of a class/primitive + // expect(value).anything(); //Matches anything + // expect(value).arrayContaining(); //Array contains specific elements + // expect(value).closeTo(); //Number is approximately equal + // expect(value).objectContaining(); // Object contains specific properties + // expect(value).stringContaining(); //String contains a substring + // expect(value).stringMatching(); //String matches a regular expression }); diff --git a/src/tests/web/example/route.spec.ts b/src/tests/web/example/route.spec.ts index 6b2b221..4e9ece7 100644 --- a/src/tests/web/example/route.spec.ts +++ b/src/tests/web/example/route.spec.ts @@ -1,8 +1,9 @@ import test from "@playwright/test"; +import { Console, log } from "console"; let fakePayloadOrders = { data: [], message: "No Users" }; -test("Intercept Network call and Fake API response", async ({ page }) => { +test("Intercept Network call and Fake/Mock API response", async ({ page }) => { await page.goto("http://xxxx.com"); await page.route("http://xxxx.com/abc/ird", async (route) => { //go the response @@ -27,3 +28,32 @@ test("Intercept Network request", async ({ page }) => { }); }); }); + +test.only("Capture Request and Response", async ({ page }) => { + page.on("request", (request) => { + console.log(request.url(), request.method()); + }); + page.on("requestfinished", (data) => { + console.log(data); + }); + + page.on("websocket", (data) => { + console.log(data.url()); + }); + + page.on("console", async (msg) => { + const values = []; + for (const arg of msg.args()) values.push(await arg.jsonValue()); + console.log(...values); + }); + + page.on("response", (response) => { + // console.log(response?.status(), response?.body()); + console.log(response?.status()); + }); + + page.on("requestfailed", (request) => { + console.log(request.url() + " " + request.failure()?.errorText); + }); + await page.goto("https://www.flipkart.com"); +}); diff --git a/src/utils/dataStore.js b/src/utils/dataStore.js new file mode 100644 index 0000000..e0f241d --- /dev/null +++ b/src/utils/dataStore.js @@ -0,0 +1,10 @@ +let store = {}; + +function saveData(key, data) { + store[key] = data; +} + +function getData(key) { + return store[key]; +} +module.exports = { saveData, getData };