-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
maximfromit
committed
Aug 20, 2024
0 parents
commit a5214b8
Showing
13 changed files
with
1,062 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
name: Playwright Tests | ||
on: | ||
push: | ||
branches: [ main, master ] | ||
pull_request: | ||
branches: [ main, master ] | ||
jobs: | ||
test: | ||
timeout-minutes: 60 | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: actions/setup-node@v4 | ||
with: | ||
node-version: lts/* | ||
- name: Install dependencies | ||
run: npm ci | ||
- name: Install Playwright Browsers | ||
run: npx playwright install --with-deps | ||
- name: Run Playwright tests | ||
run: npx playwright test | ||
- uses: actions/upload-artifact@v4 | ||
if: always() | ||
with: | ||
name: playwright-report | ||
path: playwright-report/ | ||
retention-days: 30 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
node_modules/ | ||
/test-results/ | ||
/playwright-report/ | ||
/playwright/.cache/ | ||
/test-results/ | ||
/playwright-report/ | ||
/blob-report/ | ||
/playwright/.cache/ | ||
/test-results/ | ||
/playwright-report/ | ||
/blob-report/ | ||
/playwright/.cache/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# 🐺 QA Wolf Take Home Assignment | ||
|
||
Welcome to the QA Wolf take home assignment for our [QA Engineer](https://www.notion.so/qawolf/QA-Wolf-QA-Engineer-Remote-156203a1e476459ea5e6ffca972d0efe) role! We appreciate your interest and look forward to seeing what you come up with. | ||
|
||
## Instructions | ||
|
||
This assignment has two questions as outlined below. When you are done, send [[email protected]](mailto:[email protected]) the following: | ||
|
||
1. A link to a zip file of this folder on Google Drive | ||
|
||
2. A note indicating your work location (Country/State) | ||
|
||
3. A note of how you found this job post (LinkedIn, Handshake, Wellfound, referral, etc.) | ||
|
||
### Question 1 | ||
|
||
In this assignment, you will create a script on [Hacker News](https://news.ycombinator.com/) using JavaScript and Microsoft's [Playwright](https://playwright.dev/) framework. | ||
|
||
1. Install node modules by running `npm i`. | ||
|
||
2. Edit the `index.js` file in this project to go to [Hacker News/newest](https://news.ycombinator.com/newest) and validate that EXACTLY the first 100 articles are sorted from newest to oldest. You can run your script with the `node index.js` command. | ||
|
||
Note that you are welcome to update Playwright or install other packages as you see fit, however you must utilize Playwright in this assignment. | ||
|
||
### Question 2 | ||
|
||
Why do you want to work at QA Wolf? Please record a short, ~2 min video that includes: | ||
|
||
1. Your answer | ||
|
||
2. A walk-through demonstration of your code, showing a successful execution | ||
|
||
Post the link in `why_qa_wolf.txt` (Please use [Loom](https://www.loom.com) to record your response). The answer and walkthrough should be combined into *one* video. | ||
|
||
## Frequently Asked Questions | ||
|
||
### What is your hiring process? When will I hear about next steps? | ||
|
||
This take home assignment is the first step in our hiring process, followed by a final round interview if it goes well. **We review every take home assignment submission and promise to get back to you either way within one week (usually sooner).** The only caveat is if we are out of the office, in which case we will get back to you when we return. If it has been more than one week and you have not heard from us, please do follow up. | ||
|
||
The final round interview is a 2-hour technical work session that reflects what it is like to work here. We provide a $150 stipend for your time for the final round interview regardless of how it goes. After that, there may be a short chat with our director about your experience and the role. | ||
|
||
Our hiring process is rolling where we review candidates until we have filled our openings. If there are no openings left, we will keep your contact information on file and reach out when we are hiring again. | ||
|
||
### How do you decide who to hire? | ||
|
||
We evaluate candidates based on three criteria: | ||
|
||
- Technical ability (as demonstrated in the take home and final round) | ||
- Customer service orientation (as this role is customer facing) | ||
- Alignment with our values (captured [here](https://www.notion.so/qawolf/QA-Wolf-QA-Engineer-Remote-156203a1e476459ea5e6ffca972d0efe)) | ||
|
||
This means whether we hire you is based on how you do during our interview process, not on your previous experience (or lack thereof). Note that you will also need to pass a background check to work here as our customers require this. | ||
|
||
### How can I help my application stand out? | ||
|
||
We've found that our best hires have been the most enthusiastic throughout our process. If you are very excited about working here, please feel free to go above and beyond on this assignment. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { test, expect } from '@playwright/test'; | ||
|
||
test('has title', async ({ page }) => { | ||
await page.goto('https://playwright.dev/'); | ||
|
||
// Expect a title "to contain" a substring. | ||
await expect(page).toHaveTitle(/Playwright/); | ||
}); | ||
|
||
test('get started link', async ({ page }) => { | ||
await page.goto('https://playwright.dev/'); | ||
|
||
// Click the get started link. | ||
await page.getByRole('link', { name: 'Get started' }).click(); | ||
|
||
// Expects page to have a heading with the name of Installation. | ||
await expect(page.getByRole('heading', { name: 'Installation' })).toBeVisible(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// EDIT THIS FILE TO COMPLETE ASSIGNMENT QUESTION 1 | ||
const { chromium } = require("playwright"); | ||
|
||
async function sortHackerNewsArticles() { | ||
// launch browser | ||
const browser = await chromium.launch({ headless: false }); | ||
const context = await browser.newContext(); | ||
const page = await context.newPage(); | ||
|
||
// go to Hacker News | ||
await page.goto("https://news.ycombinator.com/newest"); | ||
} | ||
|
||
(async () => { | ||
await sortHackerNewsArticles(); | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
import { test, expect, chromium } from "@playwright/test" | ||
import dayjs from "dayjs" | ||
import { link } from "fs" | ||
|
||
async function sortHackerNewsArticles() { | ||
// launch browser | ||
const browser = await chromium.launch({ headless: false }) | ||
const context = await browser.newContext() | ||
const page = await context.newPage() | ||
|
||
console.log("Navigating to Hacker News newest page...") | ||
await page.goto("https://news.ycombinator.com/newest") | ||
console.log("Page loaded.") | ||
|
||
console.log("Extracting article data...") | ||
// Locate all rows | ||
const rows = await page.getByRole("row") | ||
|
||
// Use evaluateAll to get the IDs and ranks | ||
const news = await rows.evaluateAll((rows) => { | ||
// Step 1: Extract id and rank | ||
const newsComputed = rows | ||
.map((row) => { | ||
const id = row.getAttribute("id") | ||
|
||
// Find the element with text matching the rank pattern | ||
const isMaxThreeDigitsAndDot = (value) => { | ||
return /^\d{1,3}\.$/.test(value) | ||
} | ||
const findedRank = () => { | ||
const findedRankByClassRank = Array.from( | ||
row.querySelectorAll(".rank") | ||
).find((el) => { | ||
const text = el.textContent.trim() | ||
return isMaxThreeDigitsAndDot(text) | ||
}) | ||
const findedRankByAllRow = Array.from(row.querySelectorAll("*")).find( | ||
(el) => { | ||
const text = el.textContent.trim() | ||
return isMaxThreeDigitsAndDot(text) | ||
} | ||
) | ||
if (!!findedRankByClassRank) | ||
return parseInt( | ||
findedRankByClassRank.textContent.trim().replace(".", ""), | ||
10 | ||
) | ||
if (!!findedRankByAllRow) | ||
return parseInt( | ||
findedRankByAllRow.textContent.trim().replace(".", ""), | ||
10 | ||
) | ||
return null | ||
} | ||
|
||
return { id: id ?? null, rank: findedRank() } | ||
}) | ||
.filter((item) => item.id !== null && item.rank !== null) | ||
|
||
// Step 2: Check for timestamps in subsequent rows | ||
rows.forEach((row) => { | ||
const hrefsInRowForCheck = Array.from( | ||
row.querySelectorAll("a[href]") | ||
).map((a) => a.getAttribute("href")) | ||
const idsInRowForCheck = Array.from(row.querySelectorAll("[id]")).map( | ||
(el) => el.getAttribute("id") | ||
) | ||
|
||
newsComputed.forEach((newsItem) => { | ||
if ( | ||
hrefsInRowForCheck.some((href) => href.includes(newsItem.id)) || | ||
idsInRowForCheck.some((id) => id.includes(newsItem.id)) | ||
) { | ||
const isTime = (value) => { | ||
return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/.test(value) | ||
} | ||
|
||
const findedTime = () => { | ||
const findedTimeInTitle = Array.from( | ||
row.querySelectorAll("*") | ||
).find((el) => isTime(el.getAttribute("tit2le"))) | ||
|
||
const findedTimeInAttributes = Array.from( | ||
row.querySelectorAll("*") | ||
).find((el) => { | ||
return Array.from(el.attributes).some((attr) => | ||
isTime(attr.value) | ||
) | ||
}) | ||
|
||
if (findedTimeInTitle) | ||
return findedTimeInTitle.getAttribute("title") | ||
if (findedTimeInAttributes) { | ||
return Array.from(findedTimeInAttributes.attributes).find( | ||
(attr) => isTime(attr.value) | ||
).value | ||
} | ||
return null | ||
} | ||
|
||
if (!!findedTime()) newsItem.time = findedTime() | ||
} | ||
}) | ||
}) | ||
|
||
return newsComputed | ||
}) | ||
|
||
console.log(news) | ||
} | ||
|
||
;(async () => { | ||
await sortHackerNewsArticles() | ||
})() |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"name": "qa_wolf_take_home", | ||
"version": "1.0.0", | ||
"description": "", | ||
"main": "index.js", | ||
"type": "module", | ||
"scripts": {}, | ||
"keywords": [], | ||
"author": "", | ||
"license": "ISC", | ||
"dependencies": { | ||
"dayjs": "^1.11.12", | ||
"playwright": "^1.39.0" | ||
}, | ||
"devDependencies": { | ||
"@playwright/test": "^1.46.1", | ||
"@types/node": "^20.8.9" | ||
} | ||
} |
Oops, something went wrong.