diff --git a/e2e/basic-workflow.spec.ts b/e2e/basic-workflow.spec.ts index 92367cd..9e8e007 100644 --- a/e2e/basic-workflow.spec.ts +++ b/e2e/basic-workflow.spec.ts @@ -1,30 +1,31 @@ -import { test, expect } from './fixtures/api.fixture' +import { test, expect } from './fixtures/collection.fixture' -test('checking for basic workflow functionality', async ({api, page}) => { +test('checking for basic workflow functionality', async ({apiReq, page}) => { await page.goto('/') - let result = await api.get('https://jsonplaceholder.typicode.com/todos/1') + await apiReq.get('https://jsonplaceholder.typicode.com/todos/1') + let result = await apiReq.getResponseResult() expect(result).toContain('"userId": 1') expect(result).toContain('"id": 1') expect(result).toContain('"title"') }) -test('post checking for postt request', async ({api,page}) => { +test('post checking for postt request', async ({apiReq,page}) => { await page.goto('/') - const result = await api.post('https://jsonplaceholder.typicode.com/posts', postData) + await apiReq.post('https://jsonplaceholder.typicode.com/posts', postData) + const result = await apiReq.getResponseResult() await expect(result).toContain('"title": "foo"') await expect(result).toContain('"body": "bar"') }) -test('checking for patch request', async ({api, page}) =>{ +test('checking for patch request', async ({apiReq, page}) =>{ await page.goto('/') - const result = await api.patch('https://jsonplaceholder.typicode.com/posts/1', patchData) + await apiReq.patch('https://jsonplaceholder.typicode.com/posts/1', patchData) + const result = await apiReq.getResponseResult() await expect(result).toContain('"title": "foo"') await expect(result).toContain('"id": 1') }) -const postData = `{ "title": "foo", "body": "bar", "userId" : 101}` - - +const postData = `{ "title": "foo", "body": "bar", "userId" : 101}` const patchData = `{ "id": 1, "title": "foo"}` \ No newline at end of file diff --git a/e2e/collection-test.spec.ts b/e2e/collection-test.spec.ts index b7f3c7c..bb713c1 100644 --- a/e2e/collection-test.spec.ts +++ b/e2e/collection-test.spec.ts @@ -1,4 +1,4 @@ -import {test, expect} from './fixtures/collection' +import {test, expect} from './fixtures/collection.fixture' test('check creation of new collection', async ({collection, apiReq ,page}) => { const collectionName = 'New Test Collection' @@ -18,6 +18,6 @@ test('check creation of new collection', async ({collection, apiReq ,page}) => { //4. Check if the request got saved in the collection await page.locator('div') .filter({has: page.getByTitle('Delete collection')}) - .getByRole('button').filter({hasText:collectionName}).click() + .getByRole('button',{name:collectionName}).click() await expect(page.getByText('Post 1')).toBeVisible() }) \ No newline at end of file diff --git a/e2e/complete-user-login.spec.ts b/e2e/complete-user-login.spec.ts new file mode 100644 index 0000000..fdc8357 --- /dev/null +++ b/e2e/complete-user-login.spec.ts @@ -0,0 +1,33 @@ +import {test, expect} from './fixtures/collection.fixture' + +const postData1: string = '{ "email": "eve.holt@reqres.in", "password": "cityslicka" }' +const postData2: string = '{ "name": "morpheus", "job": "leader"}' +const testData1 : string = `const varb = pm.response.json() +pm.variables.set('toki',varb.token) +console.log(pm.variables.get('toki'))` +const testData2 : string =`const varb = pm.response.json() +pm.variables.set('userId', varb.id) +console.log(pm.variables.get('userId'))` + + +test('testing miniproject', async({collection, apiReq, envSetup, page}) => { + await page.goto('/') + + await apiReq.fillHeader('x-api-key', 'reqres-free-v1') + + await envSetup.createNewEnv('QA') + await envSetup.addEnvVariable('QA', 'baseURL', 'reqres.in') + await apiReq.post('https://{{baseURL}}/api/login', postData1 ) + await expect(page).toHaveURL('/') + await apiReq.writeTest(testData1) + await collection.createCollection('User Collection') + await collection.saveToCollection('login token', 'User Collection') + await apiReq.getResponseResult() + + await apiReq.fillHeader('Authorization', '{{toki}}') + await apiReq.post('https://{{baseURL}}/api/users', postData2) + await apiReq.writeTest(testData2) + await collection.saveToCollection('login user', 'User Collection') + await apiReq.getResponseResult() + +}) \ No newline at end of file diff --git a/e2e/fixtures/collection.ts b/e2e/fixtures/collection.fixture.ts similarity index 58% rename from e2e/fixtures/collection.ts rename to e2e/fixtures/collection.fixture.ts index 42f7e89..43a6d89 100644 --- a/e2e/fixtures/collection.ts +++ b/e2e/fixtures/collection.fixture.ts @@ -1,14 +1,22 @@ import {test as base} from '@playwright/test' import { CollectionModel } from '../object-models/collection-model' import { APImodel } from '../object-models/api-model' +import { EnvSettings } from '../object-models/environment-setting.model' -export const test = base.extend<{collection: CollectionModel, apiReq: APImodel}> +export const test = base.extend<{ + collection: CollectionModel, + apiReq: APImodel, + envSetup : EnvSettings +}> ({ collection : async({page}, use) => { await use(new CollectionModel(page)) }, apiReq : async ({page},use) => { await use(new APImodel(page)) + }, + envSetup: async({page},use) => { + use(new EnvSettings(page)) } }) diff --git a/e2e/object-models/BasePage.ts b/e2e/object-models/BasePage.ts index c364113..878e412 100644 --- a/e2e/object-models/BasePage.ts +++ b/e2e/object-models/BasePage.ts @@ -1,9 +1,17 @@ import {type Page, Locator} from '@playwright/test' - - export class BasePage { - constructor(protected page:Page) {} + constructor(protected page:Page) { + + if (process.env.THROTLE) { + (async () => { + const context = this.page.context(); + const cdpSession = await context.newCDPSession(this.page); + await cdpSession.send('Emulation.setCPUThrottlingRate', { rate: 6 }); + + })() + } + } protected button(btnName: string): Locator { diff --git a/e2e/object-models/api-model.ts b/e2e/object-models/api-model.ts index 8501b6c..081a743 100644 --- a/e2e/object-models/api-model.ts +++ b/e2e/object-models/api-model.ts @@ -6,58 +6,72 @@ export class APImodel extends BasePage { constructor(page:Page) {super(page) } - - fillUrl : Locator = this.page.getByPlaceholder('https://api.example.com/endpoint') - sendBtn : Locator = this.page.getByRole('button', {name:'Send'}) - responseBody : Locator = this.page.locator('div').filter({hasText:'Body'}) - .filter({hasText:'Compare'}).last() - .getByRole('presentation') - reqType : Locator = this.page.getByRole('combobox') - reqBody : Locator = this.page.locator('div',{hasText:'Request Body (JSON)', - has: this.page.getByRole('presentation')}) - .last() - .getByRole('textbox') + reqBuilderMain : Locator = this.page.locator('#_R_5klrlb_') + fillUrl : Locator = this.reqBuilderMain.getByPlaceholder('https://api.example.com/endpoint') + sendBtn : Locator = this.reqBuilderMain.getByRole('button', {name:'Send'}) + responseSec : Locator = this.page.locator('#_R_9klrlb_') + responseBody : Locator = this.responseSec.getByRole('presentation') + reqType : Locator = this.reqBuilderMain.getByRole('combobox') + reqBodySection : Locator = this.reqBuilderMain.locator('div',{hasText:'Headers'}).getByRole('button',{name: 'Body'}) + reqBody : Locator = this.reqBuilderMain.locator('div').filter({has: this.page.getByRole('presentation')}) + .filter({hasText:'Request Body (JSON)'}).last() + .getByRole('textbox') + reqHeaderSection: Locator = this.reqBuilderMain.getByRole('button',{name:'Headers'}) + reqAddNewHeader : Locator = this.reqBuilderMain.getByRole('button',{name:'+ Add Header'}) + reqHeaderName : Locator = this.reqBuilderMain.getByPlaceholder('Header name').last() + reqHeaderValue : Locator = this.reqBuilderMain.getByPlaceholder('Header value').last() + reqTestSec : Locator = this.reqBuilderMain.getByRole('button',{name:'Tests'}) + reqTestTextBox : Locator = this.page.locator('div') + .filter({has:this.page.getByRole('presentation')}) + .filter({hasText:'Tests (Post-response Script)'}).last() + .getByRole('textbox') async get(url:string):Promise { await this.fillUrl.fill(url) await this.reqType.selectOption('GET') - await this.sendBtn.click() - return await this.getResponseResult() } async post(url: string, data : string) - { - await this.fillUrl.fill(url) - await this.reqType.selectOption('POST') - await this.fillRequestBody(data) - await this.sendBtn.click() - return await this.getResponseResult() - } + {await this.apiwrap('POST', url, data)} async patch(url: string, data: string) - { - await this.fillUrl.fill(url) - await this.reqType.selectOption('PATCH') - await this.fillRequestBody(data) - await this.sendBtn.click() - return await this.getResponseResult() - } + {await this.apiwrap('PATCH', url, data)} - private async fillRequestBody (data: string) - { + private async fillRequestBody (data: string) { await this.clearall(this.reqBody) await this.reqBody.fill(data) } - private async getResponseResult() - { - await this.page.waitForLoadState('domcontentloaded') + async getResponseResult() { + await this.sendBtn.click() + await this.page.waitForLoadState('networkidle') await this.responseBody.locator('.view-line').last().textContent() let result = await this.responseBody.textContent() result = result.replace(/\u00A0/g, ' ') return result } + + private async apiwrap(method:string, url:string, data: string) {{ + await this.fillUrl.fill(url) + await this.reqType.selectOption(method) + await this.reqBodySection.click() + await this.fillRequestBody(data) + } + } + + async fillHeader(hName:string, hValue: string) { + await this.reqHeaderSection.click() + await this.reqAddNewHeader.click() + await this.reqHeaderName.fill(hName) + await this.reqHeaderValue.fill(hValue) + } + + async writeTest(testData:string) { + await this.reqTestSec.click() + await this.clearall(this.reqTestTextBox) + await this.reqTestTextBox.fill(testData) + } } \ No newline at end of file diff --git a/e2e/object-models/collection-model.ts b/e2e/object-models/collection-model.ts index bcc1f01..bcbc09e 100644 --- a/e2e/object-models/collection-model.ts +++ b/e2e/object-models/collection-model.ts @@ -26,6 +26,6 @@ export class CollectionModel extends BasePage { .filter({ hasText: 'Select Collection' }).last() await collDiv.getByRole('textbox').fill(postNam) await collDiv.getByRole('button').filter({ hasText: collNam }).click() - await collDiv.getByLabel('Request Name (optional)').waitFor({ state: 'hidden' }) + await collDiv.waitFor({ state: 'detached' }) } } diff --git a/e2e/object-models/environment-setting.model.ts b/e2e/object-models/environment-setting.model.ts new file mode 100644 index 0000000..6198e8e --- /dev/null +++ b/e2e/object-models/environment-setting.model.ts @@ -0,0 +1,41 @@ +import { BasePage} from "./BasePage"; +import { type Page, Locator } from "@playwright/test"; + +export class EnvSettings extends BasePage { + constructor(page:Page) { + super(page) + } + envSec : Locator = this.page.getByRole('button',{name:'Environment'}) + envDiv : Locator = this.page.locator('//div') + .filter({has: this.envSec}) + .filter({has: this.page + .getByRole('heading',{name:'Environment'})}).last() + createNewEnvBtn : Locator = this.envDiv.getByRole('button', {name:'+ New'}) + saveNewEnvBtn : Locator = this.envDiv.getByRole('button',{name: 'Create'}) + envNameInput : Locator = this.envDiv.getByPlaceholder('Environment name') + addEnvVarBtn : Locator = this.envDiv.getByRole('button', {name:'+ Add'}) + envVarNameInput : Locator = this.envDiv.getByPlaceholder('Variable name', {exact: true}) + envVarValueInput : Locator = this.envDiv.getByPlaceholder('Value') + envVarSaveBtn : Locator = this.envDiv.getByTitle('Add variable') + envVarSaveConfirm : Locator = this.envDiv.getByRole('button', {name: 'Save'}) + + async createNewEnv(envName:string) { + await this.envSec.click() + await this.createNewEnvBtn.click() + await this.envNameInput.fill(envName) + await this.saveNewEnvBtn.click() + } + + async addEnvVariable(envName:string , varName:string, varValue: string) { + await this.envDiv.locator('div', {hasText: envName}) + .filter({hasText: 'Edit'}).last() + .getByRole('button', {name: 'Edit'}).click() + await this.addEnvVarBtn.click() + await this.envVarNameInput.fill(varName) + await this.envVarValueInput.fill(varValue) + await this.envVarSaveBtn.click() + await this.envVarSaveConfirm.click() + } + + +} \ No newline at end of file diff --git a/src/components/RequestBuilder.tsx b/src/components/RequestBuilder.tsx index 2250925..b82105a 100644 --- a/src/components/RequestBuilder.tsx +++ b/src/components/RequestBuilder.tsx @@ -261,6 +261,11 @@ export default function RequestBuilder({ selectedHistoryItem, selectedRequest }: if (selectedRequest.body) { setBody(selectedRequest.body); } + + if (selectedRequest.postScript) { + setTestScript(selectedRequest.postScript) + } + } }, [selectedRequest]); @@ -489,6 +494,7 @@ export default function RequestBuilder({ selectedHistoryItem, selectedRequest }: method, url: url.trim(), headers: headersObject, + postScript: METHODS_WITH_BODY.includes(method) ? testScript : undefined, params: {}, body: METHODS_WITH_BODY.includes(method) ? body : undefined, createdAt: new Date(), diff --git a/src/types/index.ts b/src/types/index.ts index f2aa620..377be9c 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -6,6 +6,7 @@ export interface Request { headers: Record; params: Record; body?: string; + postScript?: string; createdAt: Date; updatedAt: Date; }