diff --git a/.github/workflows/CronWorkflow.yml b/.github/workflows/CronWorkflow.yml index 173b3c9..ef87183 100644 --- a/.github/workflows/CronWorkflow.yml +++ b/.github/workflows/CronWorkflow.yml @@ -2,7 +2,7 @@ name: Playwright / Sanity / Cron on: schedule: - - cron: '0 */23 * * *' + - cron: '0 6 * * *' jobs: diff --git a/Utils/pageobjects-tsc/4_Resume.ts b/Utils/pageobjects-tsc/4_Resume.ts index 5a51370..a1f0206 100644 --- a/Utils/pageobjects-tsc/4_Resume.ts +++ b/Utils/pageobjects-tsc/4_Resume.ts @@ -4,49 +4,21 @@ export class Resume { readonly page: Page; readonly ResumeTitle: Locator; - readonly CoursesTitle: Locator; - readonly MySkillsTitle: Locator; - readonly FirstCourse: Locator; - readonly FirstCourseTitle: Locator; - readonly FirstCourseCompleted: Locator; - readonly FirstCourseDescription: Locator; - readonly SecondCourse: Locator; - readonly SecondCourseTitle: Locator; - readonly SecondCourseCompleted: Locator; - readonly SecondCourseDescription: Locator; - readonly SecondCourseDownload: Locator; - readonly ThirdCourse: Locator; - readonly ThirdCourseTitle: Locator; - readonly ThirdCourseCompleted: Locator; - readonly ThirdCourseDescription: Locator; - readonly SkillsDiv: Locator; - readonly SkillsNameAndPercentage: Locator; - readonly SkillsDownloadCV: Locator; - readonly SkillsInfo: Locator; + readonly ResumeCVBtn: Locator; + readonly CoursesTitles: Locator; + readonly CoursesTimeStamp: Locator; + readonly CoursesDescription: Locator; + readonly CoursesBtns: Locator; constructor(page: Page) { this.page = page this.ResumeTitle = page.getByTestId('ResumeTitle'); - this.CoursesTitle = page.getByTestId('CoursesTitle'); - this.MySkillsTitle = page.getByTestId('SkillsTitle'); - this.FirstCourse = page.getByTestId('Course1'); - this.FirstCourseTitle = this.FirstCourse.locator('h3'); - this.FirstCourseCompleted = this.FirstCourse.locator('time'); - this.FirstCourseDescription = this.FirstCourse.locator('p'); - this.SecondCourse = page.getByTestId('Course2'); - this.SecondCourseTitle = this.SecondCourse.locator('h3'); - this.SecondCourseCompleted = this.SecondCourse.locator('time'); - this.SecondCourseDescription = this.SecondCourse.locator('p'); - this.SecondCourseDownload = this.SecondCourse.locator('a'); - this.ThirdCourse = page.getByTestId('Course3'); - this.ThirdCourseTitle = this.ThirdCourse.locator('h3'); - this.ThirdCourseCompleted = this.ThirdCourse.locator('time'); - this.ThirdCourseDescription = this.ThirdCourse.locator('p'); - this.SkillsDiv = page.getByTestId('SkillsDiv'); - this.SkillsInfo = page.getByTestId('SkillsInfo'); - this.SkillsNameAndPercentage = this.SkillsInfo.getByTestId('SkillsName'); - this.SkillsDownloadCV = this.SkillsDiv.locator('a'); + this.ResumeCVBtn = page.locator('#resume a').last(); + this.CoursesTitles = page.locator("#resume h3"); + this.CoursesTimeStamp = page.locator("#resume time"); + this.CoursesDescription = page.locator("#resume p"); + this.CoursesBtns = page.locator("#resume li a"); } } \ No newline at end of file diff --git a/src/assets/files/MyResume.pdf b/src/assets/files/MyResume.pdf index a43efeb..6248e2b 100644 Binary files a/src/assets/files/MyResume.pdf and b/src/assets/files/MyResume.pdf differ diff --git a/src/components/About/index.js b/src/components/About/index.js index 4cb940f..c3beb94 100644 --- a/src/components/About/index.js +++ b/src/components/About/index.js @@ -44,6 +44,19 @@ export default function About() { I work with: Playwright Typescript, Github Actions, Postman.

I'm learning: Jenkins, ISTQB, Docker, Ruby. +

+

+ My skills:

+ ◻️ ✅ Playwright (automation)

+ ◻️ ✅ CI/CD - GitHub Actions

+ ◻️ ✅ GIT

+ ◻️ ✅ GraphQL - Altair

+ ◻️ ✅ REST API - Postman

+ ◻️ ✅ TypeScript

+ ◻️ ✅ Jira / Asana

+ ◻️ ✅ Agile / Scrum

+ ◻️ ✅ SQL - PostgreSQL / pgAdmin

+ ◻️ ✅ ISTQB Methodologies

diff --git a/src/components/Resume/BarGraph.js b/src/components/Resume/BarGraph.js deleted file mode 100644 index 8e5e538..0000000 --- a/src/components/Resume/BarGraph.js +++ /dev/null @@ -1,19 +0,0 @@ -export default function BarGraph({ name, percent }) { - return ( -
-
-

{name}

-

{percent}%

-
-
-
-
-
- ); -} diff --git a/src/components/Resume/index.js b/src/components/Resume/index.js index 774fe91..9048988 100644 --- a/src/components/Resume/index.js +++ b/src/components/Resume/index.js @@ -1,15 +1,14 @@ -import BarGraph from "./BarGraph"; import DownloadIcon from "@mui/icons-material/Download"; export default function Resume() { return (
- Resume + Resume & Courses
-
+
    -
    Courses
    +
  1. Learned how to use JS and TS in Playwright framework to automate frontend and backend testing on my projects. -

    No certificate here as I finished this course on a shared udemy account.

  2. @@ -83,7 +81,7 @@ export default function Resume() { Download Certificate
  3. -
  4. +
  5. -
  6. +
+
    +
    +
  1. + + + +

    + SQL +

    + +

    + I've learned SQL for querying databases and performing data analysis. +

    I'm confident in listing SQL and PostgreSQL on my resume. +

    +
  2. +
  3. + + + +

    + BDD - Behavioral Driven Development +

    + +

    + I learned the basics, workflow, and implementation of BDD in projects. +

    +
  4. +
  5. + + + +

    + C# programming language +

    + +

    + I learned C# basics, including variables, loops, and objects. +

    I also covered OOP concepts, exception handling, and file operations. +

    +
  6. +
  7. - Next on my radar: ISTQB + ISTQB + Foundation Level

    This milestone is set as my next goal to become an outstanding QA tester.

- -
-
My Skills
-
- - - - - - -
- - + Download CV -
-
); } diff --git a/tests/2_Home.spec.ts b/tests/2_Home.spec.ts index 6857c32..b8d33f8 100644 --- a/tests/2_Home.spec.ts +++ b/tests/2_Home.spec.ts @@ -30,7 +30,7 @@ test('Home_Text_Visibility @core', async ({browser})=> await test.step("Check if the info/credits text is visible & check the text", async () => { await expect(home.InfoMessage).toBeVisible(); - await expect(home.InfoMessage).toHaveText("This page is for automation testing purposes. View it in desktop view only."); + await expect(home.InfoMessage).toHaveText("This page is for automation testing purposes.View it in desktop view only."); }); await test.step("Check if the Welcome text is visible & check the text", async () => { diff --git a/tests/4_Resume.spec.ts b/tests/4_Resume.spec.ts index 3e436a9..f6e68d5 100644 --- a/tests/4_Resume.spec.ts +++ b/tests/4_Resume.spec.ts @@ -29,23 +29,21 @@ test('Resume_General_Sections_Visibility @core', async ({browser})=> await sidebar.ResumeTab.click(); }); - await test.step("Check if the titles and download CV are visible", async () => { - await expect(resume.CoursesTitle).toHaveText("Courses"); - await expect(resume.MySkillsTitle).toHaveText("My Skills"); - await expect(resume.ResumeTitle).toHaveText("Resume"); - await expect(resume.SkillsDownloadCV).toHaveText("Download CV"); + await test.step("Check if the title and download CV are visible", async () => { + await expect(resume.ResumeTitle).toHaveText("Resume & Courses"); + await expect(resume.ResumeCVBtn).toBeVisible(); }); await test.step("Check download CV button on click", async () => { const downloadPromise = page.waitForEvent('download'); - await resume.SkillsDownloadCV.click(); + await resume.ResumeCVBtn.click(); await downloadPromise; }); await page.close(); }); -test('Resume_Courses_Check_each_course @core', async ({browser})=> +test('Resume_Courses_Check_Each_Course_Part1 @core', async ({browser})=> { test.info().annotations.push({type: "severity", description: "Critical"}); @@ -66,42 +64,51 @@ test('Resume_Courses_Check_each_course @core', async ({browser})=> await sidebar.ResumeTab.click(); }); - await test.step("Check playwright automation course", async () => { - await expect(resume.FirstCourseCompleted).toHaveText("Completed on September, 2022"); - await expect(resume.FirstCourseDescription).toContainText("Learned how to use JS and TS"); - await expect(resume.FirstCourseTitle).toHaveText("Playwright automation"); + await test.step("Check 1 Course - Playwright automation", async () => { + await expect(resume.CoursesTimeStamp.nth(0)).toHaveText("Completed on September, 2022"); + await expect(resume.CoursesDescription.nth(0)).toContainText("Learned how to use JS and TS"); + await expect(resume.CoursesTitles.nth(0)).toHaveText("Playwright automation"); }); - await test.step("Check javascript and typescript course", async () => { - await expect(resume.SecondCourseCompleted).toHaveText("Completed on August, 2022"); - await expect(resume.SecondCourseDescription).toContainText("Learned both programming languages"); - await expect(resume.SecondCourseTitle).toHaveText("JavaScript and TypeScript"); - await expect(resume.SecondCourseDownload).toHaveText("Download Certificate"); + await test.step("Check 2 Course - JavaScript and TypeScript", async () => { + await expect(resume.CoursesTimeStamp.nth(1)).toHaveText("Completed on August, 2022"); + await expect(resume.CoursesDescription.nth(1)).toContainText("Learned both programming languages"); + await expect(resume.CoursesTitles.nth(1)).toHaveText("JavaScript and TypeScript"); + await expect(resume.CoursesBtns.nth(0)).toHaveText("Download Certificate"); }); await test.step("Check the Download Certificate btn", async () => { const [CertificatePage] = await Promise.all([ webContext.waitForEvent('page'), - resume.SecondCourseDownload.click() + resume.CoursesBtns.nth(0).click() ]); await expect(CertificatePage).toHaveURL("https://www.sololearn.com/Certificate/CT-HATAHI2L/png"); await CertificatePage.close(); }); - await test.step("Check next on radar course", async () => { - await expect(resume.ThirdCourseCompleted).toHaveText("To be completed"); - await expect(resume.ThirdCourseDescription).toContainText("This milestone is set as my next goal"); - await expect(resume.ThirdCourseTitle).toHaveText("Next on my radar: ISTQB"); + await test.step("Check 3 Course - Postman Backend Automation", async () => { + await expect(resume.CoursesTimeStamp.nth(2)).toHaveText("Completed on June, 2023"); + await expect(resume.CoursesDescription.nth(2)).toContainText("Learned how to automate backend testing with Postman."); + await expect(resume.CoursesTitles.nth(2)).toHaveText("Postman Backend Automation"); + }); + + await test.step("Check the Check my code btn", async () => { + const [PostmanCodePage] = await Promise.all([ + webContext.waitForEvent('page'), + resume.CoursesBtns.nth(1).click() + ]); + await expect(PostmanCodePage).toHaveURL("https://www.postman.com/interstellar-eclipse-418940/workspace/api-automation-course-workspace/overview"); + await PostmanCodePage.close(); }); await page.close(); }); -test('Resume_MySkills @core', async ({browser})=> +test('Resume_Courses_Check_Each_Course_Part2 @core', async ({browser})=> { test.info().annotations.push({type: "severity", description: "Critical"}); - test.info().annotations.push({type: "Description", description: "This test verifies if the skills sections has loaded properly"}); + test.info().annotations.push({type: "Description", description: "This test verifies if all courses has loaded properly"}); const webContext = await browser.newContext(); const page = await webContext.newPage(); @@ -118,28 +125,28 @@ test('Resume_MySkills @core', async ({browser})=> await sidebar.ResumeTab.click(); }); - await test.step("Check the first skill and its percentage", async () => { - await expect(resume.SkillsNameAndPercentage.nth(0)).toHaveText("JavaScript65%"); - }); - - await test.step("Check the second skill and its percentage", async () => { - await expect(resume.SkillsNameAndPercentage.nth(1)).toHaveText("TypeScript60%"); - }); - - await test.step("Check the third skill and its percentage", async () => { - await expect(resume.SkillsNameAndPercentage.nth(2)).toHaveText("Playwright - Autmation testing80%"); + await test.step("Check 4 Course - SQL", async () => { + await expect(resume.CoursesTimeStamp.nth(3)).toHaveText("Completed on July, 2023"); + await expect(resume.CoursesDescription.nth(3)).toContainText("I've learned SQL for querying databases"); + await expect(resume.CoursesTitles.nth(3)).toHaveText("SQL"); }); - await test.step("Check the fourth skill and its percentage", async () => { - await expect(resume.SkillsNameAndPercentage.nth(3)).toHaveText("Creating documentation90%"); + await test.step("Check 5 Course - BDD - Behavioral Driven Development", async () => { + await expect(resume.CoursesTimeStamp.nth(4)).toHaveText("Completed on September, 2022"); + await expect(resume.CoursesDescription.nth(4)).toContainText("I learned the basics, workflow, and implementation of BDD"); + await expect(resume.CoursesTitles.nth(4)).toHaveText("BDD - Behavioral Driven Development"); }); - await test.step("Check the fifth skill and its percentage", async () => { - await expect(resume.SkillsNameAndPercentage.nth(4)).toHaveText("Manual frontend testing90%"); + await test.step("Check 6 Course - C# programming language", async () => { + await expect(resume.CoursesTimeStamp.nth(5)).toHaveText("Completed on September, 2023"); + await expect(resume.CoursesDescription.nth(5)).toContainText("I learned C# basics"); + await expect(resume.CoursesTitles.nth(5)).toHaveText("C# programming language"); }); - await test.step("Check the sixth skill and its percentage", async () => { - await expect(resume.SkillsNameAndPercentage.nth(5)).toHaveText("Manual backend testing65%"); + await test.step("Check 7 Course - ISTQB Foundation Level", async () => { + await expect(resume.CoursesTimeStamp.nth(6)).toHaveText("To be completed on 13.10.2023"); + await expect(resume.CoursesDescription.nth(6)).toContainText("This milestone is set as my next goal"); + await expect(resume.CoursesTitles.nth(6)).toHaveText("ISTQB Foundation Level"); }); await page.close(); diff --git a/tests/5_Projects.spec.ts b/tests/5_Projects.spec.ts index f6825cf..14941ba 100644 --- a/tests/5_Projects.spec.ts +++ b/tests/5_Projects.spec.ts @@ -64,7 +64,7 @@ test('Projects_Check_Each_Project @core', async ({browser})=> await expect(projects.ProjectDescription.nth(0)).toHaveText("A Pinterest alternative for many other things."); await expect(projects.ProjectTags.nth(0).nth(0)).toHaveText("Automation / Playwright"); await expect(projects.ProjectTags.nth(1).nth(0)).toHaveText("Manual"); - await expect(projects.ProjectTileImg.nth(0)).toHaveAttribute("src","https://miro.medium.com/v2/resize:fit:646/1*gMiUPuRGC36nxZHe2zthOg.png"); + await expect(projects.ProjectTileImg.nth(0)).toHaveAttribute("src","https://d4y70tum9c2ak.cloudfront.net/contentImage/cp-xkfWuQLB8A-LnxHmXAXyjr697tiDTJ-H-hSl1VjA/resized.png"); }); await test.step("Check the first tile link", async () => { @@ -92,39 +92,58 @@ test('Projects_Check_Each_Project @core', async ({browser})=> await SecondTileLink.close(); }); - await test.step("Check the third tile info", async () => { - await expect(projects.ProjectName.nth(2)).toHaveText("Payment Social Platform (NDA)"); - await expect(projects.ProjectDescription.nth(2)).toContainText("A Social plaform for easier payment options"); - await expect(projects.ProjectTags.nth(2)).toHaveText("Manual"); - await expect(projects.ProjectTileImg.nth(2)).toHaveAttribute("src","https://erepublic.brightspotcdn.com/dims4/default/343c604/2147483647/strip/true/crop/770x374+0+69/resize/1440x700!/quality/90/?url=http%3A%2F%2Ferepublic-brightspot.s3.amazonaws.com%2Faa%2F6b%2F1a5404996431a2071cf7a016cadf%2Fshutterstock-cash-payments.jpg"); - }); - - await test.step("Check the third tile link", async () => { - const [ThirdTileLink] = await Promise.all([ - webContext.waitForEvent('page'), - projects.ProjectLink.nth(2).click() - ]); - await expect(ThirdTileLink).toHaveURL("https://www.investopedia.com/thmb/J8DhyqDJiZtjb3oOcbPEyA5aLxo=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/Term-Definitions_NDA-438a26fefa014d06b83b75b02d8403a6.jpg"); - await ThirdTileLink.close(); - }); - - await test.step("Check the fourth tile info", async () => { - await expect(projects.ProjectName.nth(3)).toHaveText("Weird West"); - await expect(projects.ProjectDescription.nth(3)).toContainText("Weird West is an action role-playing video game"); - await expect(projects.ProjectTags.nth(3)).toHaveText("Manual"); - await expect(projects.ProjectTileImg.nth(3)).toHaveAttribute("src","https://cdn.akamai.steamstatic.com/steam/apps/1097350/capsule_616x353.jpg?t=1683561276"); - }); - - await test.step("Check the fourth tile link", async () => { - const [FourthTileLink] = await Promise.all([ - webContext.waitForEvent('page'), - projects.ProjectLink.nth(3).click() - ]); - await expect(FourthTileLink).toHaveURL("https://store.steampowered.com/app/1097350/Weird_West_Definitive_Edition/"); - await FourthTileLink.close(); - }); - - await page.close(); + //NEED TO REWORK THIS TEST TO BE LESS STATIC (DYNAMIC IDs) + + // await test.step("Check the third tile info", async () => { + // await expect(projects.ProjectName.nth(2)).toHaveText("My E2E Automation Project"); + // await expect(projects.ProjectDescription.nth(2)).toContainText("My E2E Automation Project with Playwright"); + // await expect(projects.ProjectTags.nth(0).nth(2)).toHaveText("Automation / Playwright"); + // await expect(projects.ProjectTags.nth(1).nth(2)).toHaveText("Manual"); + // await expect(projects.ProjectTileImg.nth(2)).toHaveAttribute("src","https://miro.medium.com/v2/resize:fit:646/1*gMiUPuRGC36nxZHe2zthOg.png"); + // }); + + // await test.step("Check the third tile link", async () => { + // const [ThirdTileLink] = await Promise.all([ + // webContext.waitForEvent('page'), + // projects.ProjectLink.nth(2).click() + // ]); + // await expect(ThirdTileLink).toHaveURL("https://github.com/datguychen/My-Portfolio-Page/actions"); + // await ThirdTileLink.close(); + // }); + + // await test.step("Check the fourth tile info", async () => { + // await expect(projects.ProjectName.nth(3)).toHaveText("Payment Social Platform (NDA)"); + // await expect(projects.ProjectDescription.nth(3)).toContainText("A Social plaform for easier payment options"); + // await expect(projects.ProjectTags.nth(3)).toHaveText("Manual"); + // await expect(projects.ProjectTileImg.nth(3)).toHaveAttribute("src","https://erepublic.brightspotcdn.com/dims4/default/343c604/2147483647/strip/true/crop/770x374+0+69/resize/1440x700!/quality/90/?url=http%3A%2F%2Ferepublic-brightspot.s3.amazonaws.com%2Faa%2F6b%2F1a5404996431a2071cf7a016cadf%2Fshutterstock-cash-payments.jpg"); + // }); + + // await test.step("Check the fourth tile link", async () => { + // const [FourthTileLink] = await Promise.all([ + // webContext.waitForEvent('page'), + // projects.ProjectLink.nth(3).click() + // ]); + // await expect(FourthTileLink).toHaveURL("https://www.investopedia.com/thmb/J8DhyqDJiZtjb3oOcbPEyA5aLxo=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/Term-Definitions_NDA-438a26fefa014d06b83b75b02d8403a6.jpg"); + // await FourthTileLink.close(); + // }); + + // await test.step("Check the fifth tile info", async () => { + // await expect(projects.ProjectName.nth(4)).toHaveText("Weird West"); + // await expect(projects.ProjectDescription.nth(4)).toContainText("Weird West is an action role-playing video game"); + // await expect(projects.ProjectTags.nth(4)).toHaveText("Manual"); + // await expect(projects.ProjectTileImg.nth(4)).toHaveAttribute("src","https://cdn.akamai.steamstatic.com/steam/apps/1097350/capsule_616x353.jpg?t=1683561276"); + // }); + + // await test.step("Check the fourth tile link", async () => { + // const [FifthTileLink] = await Promise.all([ + // webContext.waitForEvent('page'), + // projects.ProjectLink.nth(4).click() + // ]); + // await expect(FifthTileLink).toHaveURL("https://store.steampowered.com/app/1097350/Weird_West_Definitive_Edition/"); + // await FifthTileLink.close(); + // }); + + // await page.close(); }); /*