-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Playwright test #51
Playwright test #51
Changes from 5 commits
f8f8a05
3c2d7ef
a53f549
42c1693
3b297a7
7bdbb5e
d718774
39b760b
abb1b1a
bf86152
5e5666c
2d8c9b6
39d8f24
fd13965
dda9e6b
0c13af5
9d37825
3774444
f94fb5d
005c6d2
81cb704
4f31aea
f1e584c
8245171
edac40f
714a12f
8dfd266
a96a237
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { id } from "./playwrightUtils.js"; | ||
|
||
export const DESIGNER = "designer" | ||
export const VISUALIZER = "visualizer" | ||
|
||
//Objects defining paths, aliases, and wait conditions for intercepting certain API requests. | ||
export const extension = { | ||
path: "/api/provider/extension*", | ||
alias: "extensionFileLoad" | ||
}; | ||
|
||
export const designEndpoint = { | ||
path: "/api/pattern*", | ||
alias: "designEp", | ||
wait: "@designEp", | ||
absolutePath: "/api/pattern" | ||
} | ||
|
||
export const MESHMAP_PATH = "/extension/meshmap"; | ||
|
||
export const CANVAS_CONTAINER_ID = "py-canvas-container" | ||
|
||
export const TIME = { | ||
SMALL: 500, | ||
MEDIUM: 1000, | ||
LARGE: 1500, | ||
XLARGE: 2000, | ||
XXLARGE: 5000, | ||
XXXLARGE: 10000, | ||
X4LARGE: 15_000 | ||
} | ||
|
||
export const canvasContainer = { | ||
query: id(CANVAS_CONTAINER_ID), | ||
alias: "canvas" | ||
} | ||
|
||
export const playwrightTestDesign = { | ||
url: "/extension/meshmap?design=142f0054-d9ae-4352-8618-887104a81928", | ||
id: "142f0054-d9ae-4352-8618-887104a81928", | ||
} | ||
//Objects related to specific designs or patterns within the application. | ||
export const hierarchyRelationshipDesign = cypressTestDesign; | ||
|
||
// An object specifying a URL, HTTP method, and aliases related to pattern conversion. | ||
export const cytoConversion = { | ||
url: "/api/pattern?output=cytoscape", | ||
method: "POST", | ||
alias: "cytoPatternConversion", | ||
wait: "@cytoPatternConversion" | ||
} | ||
|
||
/** | ||
* Selection and general Event Binding Layer | ||
*/ | ||
export const canvasLayer0 = { | ||
query: '[data-id="layer0-selectbox"]', | ||
alias: "layer0" | ||
} | ||
|
||
/** | ||
* drag and drop Layer | ||
*/ | ||
export const canvasLayer1 = { | ||
query: '[data-id="layer1-drag"]', | ||
alias: "layer1" | ||
} | ||
|
||
/** | ||
* Node and Element Layer | ||
*/ | ||
export const canvaslayer2 = { | ||
query: '[data-id="layer2-node"]', | ||
alias: "layer2" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
//@ts-check | ||
import { waitFor, id, InitialEnvSetup, captureAndSaveScreenshot, saveGraph, Login, setViewportSize,interceptAndModifyRequest, navigateToCustomURL, waitForNetworkResponse } from "./playwrightUtils" | ||
|
||
|
||
//Set Up Playwright capabilities | ||
const doInitialSetup = () => { | ||
InitialEnvSetup() | ||
setViewportSize(); | ||
Login(); | ||
interceptAndModifyRequest(); | ||
} | ||
|
||
//a callback hook to perform actions before running individual tests | ||
export const beforeEachCallbackForCustomUrl = (customPath)=>{ | ||
doInitialSetup(); | ||
navigateToCustomURL(customPath) | ||
waitForNetworkResponse(customPath) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
//@ts-check | ||
//Playwright configurations for setting up tests | ||
const { chromium } = require("@playwright/test"); | ||
const path = require('path'); | ||
const browser = await chromium.launch(); | ||
const context = await browser.newContext(); | ||
const page = await context.newPage(); | ||
|
||
const getFormattedDateTime = () =>{ | ||
const now = new Date(); | ||
|
||
// Extract date components (YYYY_MM_DD format) | ||
const year = now.getFullYear(); | ||
|
||
// Add 1 because months are 0-indexed | ||
const month = (now.getMonth() + 1).toString().padStart(2, "0"); | ||
const day = now.getDate().toString().padStart(2, "0"); | ||
|
||
// Extract time components (HH_MM_SS format) | ||
const hours = now.getHours().toString().padStart(2, "0"); | ||
const minutes = now.getMinutes().toString().padStart(2, "0"); | ||
const seconds = now.getSeconds().toString().padStart(2, "0"); | ||
|
||
// Concatenate date and time components into the desired format | ||
const formattedString = `Meshmap_${year}_${month}_${day}_${hours}_${minutes}_${seconds}.png`; | ||
|
||
return formattedString; | ||
}; | ||
|
||
//utility func to generate css selector and return id and strings | ||
function waitFor(str) { | ||
return `@${str}`; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if using $ to access the element is recommended. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. its the same method as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what do you think of the login and interceptRequests functions |
||
} | ||
|
||
function id(str) { | ||
return `#${str}`; | ||
} | ||
|
||
|
||
//create a fresh testing env for testcases | ||
async function InitialEnvSetup() { | ||
const browser = await chromium.launch(); | ||
const context = await browser.newContext(); | ||
const page = await context.newPage(); | ||
|
||
return { browser, context, page }; | ||
} | ||
|
||
|
||
//capture and save a screenshot | ||
async function captureAndSaveScreenshot(filename) { | ||
await page.screenshot({ path: filename }); | ||
} | ||
|
||
//Save meshmapscreenshot and generate a download link. | ||
async function saveGraph(customUrl) { | ||
const browser = await chromium.launch(); | ||
const page = await browser.newPage(); | ||
|
||
await page.goto(customUrl); | ||
|
||
// Capture a screenshot and save it with a custom filename | ||
const date = new Date(); | ||
// Format: Meshmap_2023_09_23_14_30_45.png | ||
const fileName = getFormattedDateTime(); | ||
const filePath = path.join(__dirname, fileName); // Full path to the saved screenshot | ||
|
||
await captureAndSaveScreenshot(filePath); | ||
await browser.close(); | ||
|
||
// Create a download link | ||
const downloadLink = `/download?fileName=${encodeURIComponent(fileName)}`; | ||
|
||
console.log(`Screenshot saved as ${fileName}`); | ||
console.log('Download link:', downloadLink); | ||
|
||
return downloadLink; | ||
} | ||
|
||
//Login to be used for settingup tests | ||
async function Login(page, username, password) { | ||
await page.goto('https://meshery.layer5.io/login'); | ||
|
||
await page.locator('input[name="identifier"]').fill(username); | ||
// Press the Tab key (to move to the password field) | ||
await page.locator('input[name="identifier"]').press('Tab'); | ||
await page.fill('input[name="password"]').fill(password); | ||
await page.getByRole('button', { name: 'Sign in', exact: true }).click(); | ||
} | ||
|
||
//set a visiblesize of webpage | ||
async function setViewportSize(width, height) { | ||
await page.setViewportSize({ width, height }); | ||
} | ||
|
||
// intercept and modify network requests to specific endpoint | ||
// to control network interactions during testing and automation | ||
async function interceptAndModifyRequest(targetUrl, modifiedResponse) { | ||
await page.route(targetUrl, (route) => { | ||
route.fulfill({ | ||
status: 200, | ||
contentType: 'application/json', | ||
body: JSON.stringify(modifiedResponse),//custom response to send when intercepting a network request | ||
}); | ||
}); | ||
} | ||
|
||
async function navigateToCustomURL(customPath) { | ||
const browser = await chromium.launch(); | ||
const context = await browser.newContext(); | ||
const page = await context.newPage(); | ||
await page.goto(customPath); | ||
} | ||
|
||
async function waitForNetworkResponse(targetUrl) { | ||
const timeout = 60000 | ||
await page.waitForResponse(targetUrl, { timeout }); | ||
} | ||
|
||
|
||
export { waitFor, id, InitialEnvSetup, captureAndSaveScreenshot, saveGraph, Login, setViewportSize, interceptAndModifyRequest, navigateToCustomURL, waitForNetworkResponse }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is
api/pattern
an endpoint?What's the use of
designEndpoint
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Philip-21, may you answer this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
its the ApiEndpoint for creating or deleting meshmap design .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Id added after it will point to a particular design, r8?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i am thinking of writing individual tests for every action but i dont think it will work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i am trying to see how i ca put everything together, for it to work