From 7305a31b53ce2f26dc176946e93e38aea9467e8b Mon Sep 17 00:00:00 2001
From: Zakaria_ <135060272+Zako563@users.noreply.github.com>
Date: Mon, 11 Nov 2024 16:56:28 -0500
Subject: [PATCH 01/14] test for get emergency by id (#1028)
**JIRA:** link to jira ticket
## Context:
What is the ticket about and why are we doing this change.
## Does this PR change the .vscode folder in petclinic-frontend?:
If the PR changes the .vscode folder, explain why in detail because it
should not.
Be sure to include cgerard321 as a reviewer.
**Reviewers need to check for any changes to the
.vscode folder and add a comment about it to their review
comments.**
## Changes
What are the various changes and what other modules do those changes
affect.
This can be bullet point or sentence format.
## Before and After UI (Required for UI-impacting PRs)
--add a test for emergency by id
If this is a change to the UI, include before and after screenshots to
show the differences.
If this is a new UI feature, include screenshots to show reviewers what
it looks like.
## Dev notes (Optional)
Specific technical changes that should be noted
## Linked pull requests (Optional)
Pull request links
Co-authored-by: Zakaria_ <135060272+tramway23@users.noreply.github.com>
---
.../tests/ViewEmergencyById.spec.ts | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
create mode 100644 petclinic-frontend/tests/ViewEmergencyById.spec.ts
diff --git a/petclinic-frontend/tests/ViewEmergencyById.spec.ts b/petclinic-frontend/tests/ViewEmergencyById.spec.ts
new file mode 100644
index 000000000..65f4b1bed
--- /dev/null
+++ b/petclinic-frontend/tests/ViewEmergencyById.spec.ts
@@ -0,0 +1,17 @@
+import { test, expect } from '@playwright/test';
+
+test('test', async ({ page }) => {
+ await page.goto('http://localhost:3000/users/login');
+ await page.getByPlaceholder('Enter your email').click();
+ await page.getByPlaceholder('Enter your email').fill('admin@admin.com');
+ await page.getByPlaceholder('Enter your password').click();
+ await page.getByPlaceholder('Enter your password').fill('pwd');
+ await page.getByRole('button', { name: 'Login' }).click();
+ await page.getByRole('link', { name: 'Visits' }).click();
+ await page
+ .getByRole('row', { name: 'emergencyId2' })
+ .getByRole('button')
+ .nth(2)
+ .click();
+ //await page.getByRole('button', { name: 'Return to Emergencies' }).click();
+});
From 6fb3225bfea69bc49ea5344a44ccd6c592361f36 Mon Sep 17 00:00:00 2001
From: Valentine Nneji
Date: Mon, 11 Nov 2024 17:07:12 -0500
Subject: [PATCH 02/14] Playwright test to unlist a product (#1030)
## Context:
Did a playwright test to unlist a product
---
...CoreApp,Version=v8.0.AssemblyAttributes.cs | 4 +
.../net8.0/emailing-service.AssemblyInfo.cs | 24 +
.../emailing-service.AssemblyInfoInputs.cache | 1 +
....GeneratedMSBuildEditorConfig.editorconfig | 19 +
.../net8.0/emailing-service.GlobalUsings.g.cs | 17 +
...CoreApp,Version=v8.0.AssemblyAttributes.cs | 4 +
.../net8.0/emailing-service.AssemblyInfo.cs | 24 +
.../emailing-service.AssemblyInfoInputs.cache | 1 +
....GeneratedMSBuildEditorConfig.editorconfig | 19 +
.../net8.0/emailing-service.GlobalUsings.g.cs | 17 +
petclinic-frontend/e2e/example.spec.ts | 18 +
petclinic-frontend/package-lock.json | 1 -
.../tests-examples/demo-todo-app.spec.ts | 437 ++++++++++++++++++
.../tests/shoppage/shoppagetests.spec.ts | 22 +
14 files changed, 607 insertions(+), 1 deletion(-)
create mode 100644 emailing-service/emailing-service/obj/Debug/net8.0/.NETCoreApp,Version=v8.0.AssemblyAttributes.cs
create mode 100644 emailing-service/emailing-service/obj/Debug/net8.0/emailing-service.AssemblyInfo.cs
create mode 100644 emailing-service/emailing-service/obj/Debug/net8.0/emailing-service.AssemblyInfoInputs.cache
create mode 100644 emailing-service/emailing-service/obj/Debug/net8.0/emailing-service.GeneratedMSBuildEditorConfig.editorconfig
create mode 100644 emailing-service/emailing-service/obj/Debug/net8.0/emailing-service.GlobalUsings.g.cs
create mode 100644 emailing-service/emailing-service/obj/Release/net8.0/.NETCoreApp,Version=v8.0.AssemblyAttributes.cs
create mode 100644 emailing-service/emailing-service/obj/Release/net8.0/emailing-service.AssemblyInfo.cs
create mode 100644 emailing-service/emailing-service/obj/Release/net8.0/emailing-service.AssemblyInfoInputs.cache
create mode 100644 emailing-service/emailing-service/obj/Release/net8.0/emailing-service.GeneratedMSBuildEditorConfig.editorconfig
create mode 100644 emailing-service/emailing-service/obj/Release/net8.0/emailing-service.GlobalUsings.g.cs
create mode 100644 petclinic-frontend/e2e/example.spec.ts
create mode 100644 petclinic-frontend/tests-examples/demo-todo-app.spec.ts
create mode 100644 petclinic-frontend/tests/shoppage/shoppagetests.spec.ts
diff --git a/emailing-service/emailing-service/obj/Debug/net8.0/.NETCoreApp,Version=v8.0.AssemblyAttributes.cs b/emailing-service/emailing-service/obj/Debug/net8.0/.NETCoreApp,Version=v8.0.AssemblyAttributes.cs
new file mode 100644
index 000000000..2217181c8
--- /dev/null
+++ b/emailing-service/emailing-service/obj/Debug/net8.0/.NETCoreApp,Version=v8.0.AssemblyAttributes.cs
@@ -0,0 +1,4 @@
+//
+using System;
+using System.Reflection;
+[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
diff --git a/emailing-service/emailing-service/obj/Debug/net8.0/emailing-service.AssemblyInfo.cs b/emailing-service/emailing-service/obj/Debug/net8.0/emailing-service.AssemblyInfo.cs
new file mode 100644
index 000000000..0fa1ff381
--- /dev/null
+++ b/emailing-service/emailing-service/obj/Debug/net8.0/emailing-service.AssemblyInfo.cs
@@ -0,0 +1,24 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+using System;
+using System.Reflection;
+
+[assembly: System.Reflection.AssemblyCompanyAttribute("emailing-service")]
+[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
+[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
+[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+fdaa04180dd32c36d98b3809e2447e007318db58")]
+[assembly: System.Reflection.AssemblyProductAttribute("emailing-service")]
+[assembly: System.Reflection.AssemblyTitleAttribute("emailing-service")]
+[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
+[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("emailing-service-test")]
+
+// Generated by the MSBuild WriteCodeFragment class.
+
diff --git a/emailing-service/emailing-service/obj/Debug/net8.0/emailing-service.AssemblyInfoInputs.cache b/emailing-service/emailing-service/obj/Debug/net8.0/emailing-service.AssemblyInfoInputs.cache
new file mode 100644
index 000000000..6a42217dd
--- /dev/null
+++ b/emailing-service/emailing-service/obj/Debug/net8.0/emailing-service.AssemblyInfoInputs.cache
@@ -0,0 +1 @@
+7bf0a9728cde5f1afe2ae8025a609b440ad50fe1158c532a0a20adc5d4a3bce7
diff --git a/emailing-service/emailing-service/obj/Debug/net8.0/emailing-service.GeneratedMSBuildEditorConfig.editorconfig b/emailing-service/emailing-service/obj/Debug/net8.0/emailing-service.GeneratedMSBuildEditorConfig.editorconfig
new file mode 100644
index 000000000..fbaabd102
--- /dev/null
+++ b/emailing-service/emailing-service/obj/Debug/net8.0/emailing-service.GeneratedMSBuildEditorConfig.editorconfig
@@ -0,0 +1,19 @@
+is_global = true
+build_property.TargetFramework = net8.0
+build_property.TargetPlatformMinVersion =
+build_property.UsingMicrosoftNETSdkWeb = true
+build_property.ProjectTypeGuids =
+build_property.InvariantGlobalization =
+build_property.PlatformNeutralAssembly =
+build_property.EnforceExtendedAnalyzerRules =
+build_property._SupportedPlatformList = Linux,macOS,Windows
+build_property.RootNamespace = emailing_service
+build_property.RootNamespace = emailing_service
+build_property.ProjectDir = C:\Users\nneji\Github\champlain_petclinic\emailing-service\emailing-service\
+build_property.EnableComHosting =
+build_property.EnableGeneratedComInterfaceComImportInterop =
+build_property.RazorLangVersion = 8.0
+build_property.SupportLocalizedComponentNames =
+build_property.GenerateRazorMetadataSourceChecksumAttributes =
+build_property.MSBuildProjectDirectory = C:\Users\nneji\Github\champlain_petclinic\emailing-service\emailing-service
+build_property._RazorSourceGeneratorDebug =
diff --git a/emailing-service/emailing-service/obj/Debug/net8.0/emailing-service.GlobalUsings.g.cs b/emailing-service/emailing-service/obj/Debug/net8.0/emailing-service.GlobalUsings.g.cs
new file mode 100644
index 000000000..025530a29
--- /dev/null
+++ b/emailing-service/emailing-service/obj/Debug/net8.0/emailing-service.GlobalUsings.g.cs
@@ -0,0 +1,17 @@
+//
+global using global::Microsoft.AspNetCore.Builder;
+global using global::Microsoft.AspNetCore.Hosting;
+global using global::Microsoft.AspNetCore.Http;
+global using global::Microsoft.AspNetCore.Routing;
+global using global::Microsoft.Extensions.Configuration;
+global using global::Microsoft.Extensions.DependencyInjection;
+global using global::Microsoft.Extensions.Hosting;
+global using global::Microsoft.Extensions.Logging;
+global using global::System;
+global using global::System.Collections.Generic;
+global using global::System.IO;
+global using global::System.Linq;
+global using global::System.Net.Http;
+global using global::System.Net.Http.Json;
+global using global::System.Threading;
+global using global::System.Threading.Tasks;
diff --git a/emailing-service/emailing-service/obj/Release/net8.0/.NETCoreApp,Version=v8.0.AssemblyAttributes.cs b/emailing-service/emailing-service/obj/Release/net8.0/.NETCoreApp,Version=v8.0.AssemblyAttributes.cs
new file mode 100644
index 000000000..2217181c8
--- /dev/null
+++ b/emailing-service/emailing-service/obj/Release/net8.0/.NETCoreApp,Version=v8.0.AssemblyAttributes.cs
@@ -0,0 +1,4 @@
+//
+using System;
+using System.Reflection;
+[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
diff --git a/emailing-service/emailing-service/obj/Release/net8.0/emailing-service.AssemblyInfo.cs b/emailing-service/emailing-service/obj/Release/net8.0/emailing-service.AssemblyInfo.cs
new file mode 100644
index 000000000..2b58ebfdf
--- /dev/null
+++ b/emailing-service/emailing-service/obj/Release/net8.0/emailing-service.AssemblyInfo.cs
@@ -0,0 +1,24 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+using System;
+using System.Reflection;
+
+[assembly: System.Reflection.AssemblyCompanyAttribute("emailing-service")]
+[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")]
+[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
+[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+fdaa04180dd32c36d98b3809e2447e007318db58")]
+[assembly: System.Reflection.AssemblyProductAttribute("emailing-service")]
+[assembly: System.Reflection.AssemblyTitleAttribute("emailing-service")]
+[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
+[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("emailing-service-test")]
+
+// Generated by the MSBuild WriteCodeFragment class.
+
diff --git a/emailing-service/emailing-service/obj/Release/net8.0/emailing-service.AssemblyInfoInputs.cache b/emailing-service/emailing-service/obj/Release/net8.0/emailing-service.AssemblyInfoInputs.cache
new file mode 100644
index 000000000..0dd579d33
--- /dev/null
+++ b/emailing-service/emailing-service/obj/Release/net8.0/emailing-service.AssemblyInfoInputs.cache
@@ -0,0 +1 @@
+c4cd523c82050fd023f7beda18c0487395a670c00681e1c920589e0d5671d06e
diff --git a/emailing-service/emailing-service/obj/Release/net8.0/emailing-service.GeneratedMSBuildEditorConfig.editorconfig b/emailing-service/emailing-service/obj/Release/net8.0/emailing-service.GeneratedMSBuildEditorConfig.editorconfig
new file mode 100644
index 000000000..fbaabd102
--- /dev/null
+++ b/emailing-service/emailing-service/obj/Release/net8.0/emailing-service.GeneratedMSBuildEditorConfig.editorconfig
@@ -0,0 +1,19 @@
+is_global = true
+build_property.TargetFramework = net8.0
+build_property.TargetPlatformMinVersion =
+build_property.UsingMicrosoftNETSdkWeb = true
+build_property.ProjectTypeGuids =
+build_property.InvariantGlobalization =
+build_property.PlatformNeutralAssembly =
+build_property.EnforceExtendedAnalyzerRules =
+build_property._SupportedPlatformList = Linux,macOS,Windows
+build_property.RootNamespace = emailing_service
+build_property.RootNamespace = emailing_service
+build_property.ProjectDir = C:\Users\nneji\Github\champlain_petclinic\emailing-service\emailing-service\
+build_property.EnableComHosting =
+build_property.EnableGeneratedComInterfaceComImportInterop =
+build_property.RazorLangVersion = 8.0
+build_property.SupportLocalizedComponentNames =
+build_property.GenerateRazorMetadataSourceChecksumAttributes =
+build_property.MSBuildProjectDirectory = C:\Users\nneji\Github\champlain_petclinic\emailing-service\emailing-service
+build_property._RazorSourceGeneratorDebug =
diff --git a/emailing-service/emailing-service/obj/Release/net8.0/emailing-service.GlobalUsings.g.cs b/emailing-service/emailing-service/obj/Release/net8.0/emailing-service.GlobalUsings.g.cs
new file mode 100644
index 000000000..025530a29
--- /dev/null
+++ b/emailing-service/emailing-service/obj/Release/net8.0/emailing-service.GlobalUsings.g.cs
@@ -0,0 +1,17 @@
+//
+global using global::Microsoft.AspNetCore.Builder;
+global using global::Microsoft.AspNetCore.Hosting;
+global using global::Microsoft.AspNetCore.Http;
+global using global::Microsoft.AspNetCore.Routing;
+global using global::Microsoft.Extensions.Configuration;
+global using global::Microsoft.Extensions.DependencyInjection;
+global using global::Microsoft.Extensions.Hosting;
+global using global::Microsoft.Extensions.Logging;
+global using global::System;
+global using global::System.Collections.Generic;
+global using global::System.IO;
+global using global::System.Linq;
+global using global::System.Net.Http;
+global using global::System.Net.Http.Json;
+global using global::System.Threading;
+global using global::System.Threading.Tasks;
diff --git a/petclinic-frontend/e2e/example.spec.ts b/petclinic-frontend/e2e/example.spec.ts
new file mode 100644
index 000000000..54a906a4e
--- /dev/null
+++ b/petclinic-frontend/e2e/example.spec.ts
@@ -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();
+});
diff --git a/petclinic-frontend/package-lock.json b/petclinic-frontend/package-lock.json
index f47f40a89..f28651f3a 100644
--- a/petclinic-frontend/package-lock.json
+++ b/petclinic-frontend/package-lock.json
@@ -704,7 +704,6 @@
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.2.tgz",
"integrity": "sha512-54w1xCWfXuax7dz4W2M9uw0gDyh+ti/0K/MxcCUxChFh37kkdxPdfZDw5QBbuPUJHr1CiHJ1hXgSs+GgeQc5Zw==",
"dev": true,
- "license": "Apache-2.0",
"dependencies": {
"playwright": "1.48.2"
},
diff --git a/petclinic-frontend/tests-examples/demo-todo-app.spec.ts b/petclinic-frontend/tests-examples/demo-todo-app.spec.ts
new file mode 100644
index 000000000..8641cb5f5
--- /dev/null
+++ b/petclinic-frontend/tests-examples/demo-todo-app.spec.ts
@@ -0,0 +1,437 @@
+import { test, expect, type Page } from '@playwright/test';
+
+test.beforeEach(async ({ page }) => {
+ await page.goto('https://demo.playwright.dev/todomvc');
+});
+
+const TODO_ITEMS = [
+ 'buy some cheese',
+ 'feed the cat',
+ 'book a doctors appointment'
+] as const;
+
+test.describe('New Todo', () => {
+ test('should allow me to add todo items', async ({ page }) => {
+ // create a new todo locator
+ const newTodo = page.getByPlaceholder('What needs to be done?');
+
+ // Create 1st todo.
+ await newTodo.fill(TODO_ITEMS[0]);
+ await newTodo.press('Enter');
+
+ // Make sure the list only has one todo item.
+ await expect(page.getByTestId('todo-title')).toHaveText([
+ TODO_ITEMS[0]
+ ]);
+
+ // Create 2nd todo.
+ await newTodo.fill(TODO_ITEMS[1]);
+ await newTodo.press('Enter');
+
+ // Make sure the list now has two todo items.
+ await expect(page.getByTestId('todo-title')).toHaveText([
+ TODO_ITEMS[0],
+ TODO_ITEMS[1]
+ ]);
+
+ await checkNumberOfTodosInLocalStorage(page, 2);
+ });
+
+ test('should clear text input field when an item is added', async ({ page }) => {
+ // create a new todo locator
+ const newTodo = page.getByPlaceholder('What needs to be done?');
+
+ // Create one todo item.
+ await newTodo.fill(TODO_ITEMS[0]);
+ await newTodo.press('Enter');
+
+ // Check that input is empty.
+ await expect(newTodo).toBeEmpty();
+ await checkNumberOfTodosInLocalStorage(page, 1);
+ });
+
+ test('should append new items to the bottom of the list', async ({ page }) => {
+ // Create 3 items.
+ await createDefaultTodos(page);
+
+ // create a todo count locator
+ const todoCount = page.getByTestId('todo-count')
+
+ // Check test using different methods.
+ await expect(page.getByText('3 items left')).toBeVisible();
+ await expect(todoCount).toHaveText('3 items left');
+ await expect(todoCount).toContainText('3');
+ await expect(todoCount).toHaveText(/3/);
+
+ // Check all items in one call.
+ await expect(page.getByTestId('todo-title')).toHaveText(TODO_ITEMS);
+ await checkNumberOfTodosInLocalStorage(page, 3);
+ });
+});
+
+test.describe('Mark all as completed', () => {
+ test.beforeEach(async ({ page }) => {
+ await createDefaultTodos(page);
+ await checkNumberOfTodosInLocalStorage(page, 3);
+ });
+
+ test.afterEach(async ({ page }) => {
+ await checkNumberOfTodosInLocalStorage(page, 3);
+ });
+
+ test('should allow me to mark all items as completed', async ({ page }) => {
+ // Complete all todos.
+ await page.getByLabel('Mark all as complete').check();
+
+ // Ensure all todos have 'completed' class.
+ await expect(page.getByTestId('todo-item')).toHaveClass(['completed', 'completed', 'completed']);
+ await checkNumberOfCompletedTodosInLocalStorage(page, 3);
+ });
+
+ test('should allow me to clear the complete state of all items', async ({ page }) => {
+ const toggleAll = page.getByLabel('Mark all as complete');
+ // Check and then immediately uncheck.
+ await toggleAll.check();
+ await toggleAll.uncheck();
+
+ // Should be no completed classes.
+ await expect(page.getByTestId('todo-item')).toHaveClass(['', '', '']);
+ });
+
+ test('complete all checkbox should update state when items are completed / cleared', async ({ page }) => {
+ const toggleAll = page.getByLabel('Mark all as complete');
+ await toggleAll.check();
+ await expect(toggleAll).toBeChecked();
+ await checkNumberOfCompletedTodosInLocalStorage(page, 3);
+
+ // Uncheck first todo.
+ const firstTodo = page.getByTestId('todo-item').nth(0);
+ await firstTodo.getByRole('checkbox').uncheck();
+
+ // Reuse toggleAll locator and make sure its not checked.
+ await expect(toggleAll).not.toBeChecked();
+
+ await firstTodo.getByRole('checkbox').check();
+ await checkNumberOfCompletedTodosInLocalStorage(page, 3);
+
+ // Assert the toggle all is checked again.
+ await expect(toggleAll).toBeChecked();
+ });
+});
+
+test.describe('Item', () => {
+
+ test('should allow me to mark items as complete', async ({ page }) => {
+ // create a new todo locator
+ const newTodo = page.getByPlaceholder('What needs to be done?');
+
+ // Create two items.
+ for (const item of TODO_ITEMS.slice(0, 2)) {
+ await newTodo.fill(item);
+ await newTodo.press('Enter');
+ }
+
+ // Check first item.
+ const firstTodo = page.getByTestId('todo-item').nth(0);
+ await firstTodo.getByRole('checkbox').check();
+ await expect(firstTodo).toHaveClass('completed');
+
+ // Check second item.
+ const secondTodo = page.getByTestId('todo-item').nth(1);
+ await expect(secondTodo).not.toHaveClass('completed');
+ await secondTodo.getByRole('checkbox').check();
+
+ // Assert completed class.
+ await expect(firstTodo).toHaveClass('completed');
+ await expect(secondTodo).toHaveClass('completed');
+ });
+
+ test('should allow me to un-mark items as complete', async ({ page }) => {
+ // create a new todo locator
+ const newTodo = page.getByPlaceholder('What needs to be done?');
+
+ // Create two items.
+ for (const item of TODO_ITEMS.slice(0, 2)) {
+ await newTodo.fill(item);
+ await newTodo.press('Enter');
+ }
+
+ const firstTodo = page.getByTestId('todo-item').nth(0);
+ const secondTodo = page.getByTestId('todo-item').nth(1);
+ const firstTodoCheckbox = firstTodo.getByRole('checkbox');
+
+ await firstTodoCheckbox.check();
+ await expect(firstTodo).toHaveClass('completed');
+ await expect(secondTodo).not.toHaveClass('completed');
+ await checkNumberOfCompletedTodosInLocalStorage(page, 1);
+
+ await firstTodoCheckbox.uncheck();
+ await expect(firstTodo).not.toHaveClass('completed');
+ await expect(secondTodo).not.toHaveClass('completed');
+ await checkNumberOfCompletedTodosInLocalStorage(page, 0);
+ });
+
+ test('should allow me to edit an item', async ({ page }) => {
+ await createDefaultTodos(page);
+
+ const todoItems = page.getByTestId('todo-item');
+ const secondTodo = todoItems.nth(1);
+ await secondTodo.dblclick();
+ await expect(secondTodo.getByRole('textbox', { name: 'Edit' })).toHaveValue(TODO_ITEMS[1]);
+ await secondTodo.getByRole('textbox', { name: 'Edit' }).fill('buy some sausages');
+ await secondTodo.getByRole('textbox', { name: 'Edit' }).press('Enter');
+
+ // Explicitly assert the new text value.
+ await expect(todoItems).toHaveText([
+ TODO_ITEMS[0],
+ 'buy some sausages',
+ TODO_ITEMS[2]
+ ]);
+ await checkTodosInLocalStorage(page, 'buy some sausages');
+ });
+});
+
+test.describe('Editing', () => {
+ test.beforeEach(async ({ page }) => {
+ await createDefaultTodos(page);
+ await checkNumberOfTodosInLocalStorage(page, 3);
+ });
+
+ test('should hide other controls when editing', async ({ page }) => {
+ const todoItem = page.getByTestId('todo-item').nth(1);
+ await todoItem.dblclick();
+ await expect(todoItem.getByRole('checkbox')).not.toBeVisible();
+ await expect(todoItem.locator('label', {
+ hasText: TODO_ITEMS[1],
+ })).not.toBeVisible();
+ await checkNumberOfTodosInLocalStorage(page, 3);
+ });
+
+ test('should save edits on blur', async ({ page }) => {
+ const todoItems = page.getByTestId('todo-item');
+ await todoItems.nth(1).dblclick();
+ await todoItems.nth(1).getByRole('textbox', { name: 'Edit' }).fill('buy some sausages');
+ await todoItems.nth(1).getByRole('textbox', { name: 'Edit' }).dispatchEvent('blur');
+
+ await expect(todoItems).toHaveText([
+ TODO_ITEMS[0],
+ 'buy some sausages',
+ TODO_ITEMS[2],
+ ]);
+ await checkTodosInLocalStorage(page, 'buy some sausages');
+ });
+
+ test('should trim entered text', async ({ page }) => {
+ const todoItems = page.getByTestId('todo-item');
+ await todoItems.nth(1).dblclick();
+ await todoItems.nth(1).getByRole('textbox', { name: 'Edit' }).fill(' buy some sausages ');
+ await todoItems.nth(1).getByRole('textbox', { name: 'Edit' }).press('Enter');
+
+ await expect(todoItems).toHaveText([
+ TODO_ITEMS[0],
+ 'buy some sausages',
+ TODO_ITEMS[2],
+ ]);
+ await checkTodosInLocalStorage(page, 'buy some sausages');
+ });
+
+ test('should remove the item if an empty text string was entered', async ({ page }) => {
+ const todoItems = page.getByTestId('todo-item');
+ await todoItems.nth(1).dblclick();
+ await todoItems.nth(1).getByRole('textbox', { name: 'Edit' }).fill('');
+ await todoItems.nth(1).getByRole('textbox', { name: 'Edit' }).press('Enter');
+
+ await expect(todoItems).toHaveText([
+ TODO_ITEMS[0],
+ TODO_ITEMS[2],
+ ]);
+ });
+
+ test('should cancel edits on escape', async ({ page }) => {
+ const todoItems = page.getByTestId('todo-item');
+ await todoItems.nth(1).dblclick();
+ await todoItems.nth(1).getByRole('textbox', { name: 'Edit' }).fill('buy some sausages');
+ await todoItems.nth(1).getByRole('textbox', { name: 'Edit' }).press('Escape');
+ await expect(todoItems).toHaveText(TODO_ITEMS);
+ });
+});
+
+test.describe('Counter', () => {
+ test('should display the current number of todo items', async ({ page }) => {
+ // create a new todo locator
+ const newTodo = page.getByPlaceholder('What needs to be done?');
+
+ // create a todo count locator
+ const todoCount = page.getByTestId('todo-count')
+
+ await newTodo.fill(TODO_ITEMS[0]);
+ await newTodo.press('Enter');
+
+ await expect(todoCount).toContainText('1');
+
+ await newTodo.fill(TODO_ITEMS[1]);
+ await newTodo.press('Enter');
+ await expect(todoCount).toContainText('2');
+
+ await checkNumberOfTodosInLocalStorage(page, 2);
+ });
+});
+
+test.describe('Clear completed button', () => {
+ test.beforeEach(async ({ page }) => {
+ await createDefaultTodos(page);
+ });
+
+ test('should display the correct text', async ({ page }) => {
+ await page.locator('.todo-list li .toggle').first().check();
+ await expect(page.getByRole('button', { name: 'Clear completed' })).toBeVisible();
+ });
+
+ test('should remove completed items when clicked', async ({ page }) => {
+ const todoItems = page.getByTestId('todo-item');
+ await todoItems.nth(1).getByRole('checkbox').check();
+ await page.getByRole('button', { name: 'Clear completed' }).click();
+ await expect(todoItems).toHaveCount(2);
+ await expect(todoItems).toHaveText([TODO_ITEMS[0], TODO_ITEMS[2]]);
+ });
+
+ test('should be hidden when there are no items that are completed', async ({ page }) => {
+ await page.locator('.todo-list li .toggle').first().check();
+ await page.getByRole('button', { name: 'Clear completed' }).click();
+ await expect(page.getByRole('button', { name: 'Clear completed' })).toBeHidden();
+ });
+});
+
+test.describe('Persistence', () => {
+ test('should persist its data', async ({ page }) => {
+ // create a new todo locator
+ const newTodo = page.getByPlaceholder('What needs to be done?');
+
+ for (const item of TODO_ITEMS.slice(0, 2)) {
+ await newTodo.fill(item);
+ await newTodo.press('Enter');
+ }
+
+ const todoItems = page.getByTestId('todo-item');
+ const firstTodoCheck = todoItems.nth(0).getByRole('checkbox');
+ await firstTodoCheck.check();
+ await expect(todoItems).toHaveText([TODO_ITEMS[0], TODO_ITEMS[1]]);
+ await expect(firstTodoCheck).toBeChecked();
+ await expect(todoItems).toHaveClass(['completed', '']);
+
+ // Ensure there is 1 completed item.
+ await checkNumberOfCompletedTodosInLocalStorage(page, 1);
+
+ // Now reload.
+ await page.reload();
+ await expect(todoItems).toHaveText([TODO_ITEMS[0], TODO_ITEMS[1]]);
+ await expect(firstTodoCheck).toBeChecked();
+ await expect(todoItems).toHaveClass(['completed', '']);
+ });
+});
+
+test.describe('Routing', () => {
+ test.beforeEach(async ({ page }) => {
+ await createDefaultTodos(page);
+ // make sure the app had a chance to save updated todos in storage
+ // before navigating to a new view, otherwise the items can get lost :(
+ // in some frameworks like Durandal
+ await checkTodosInLocalStorage(page, TODO_ITEMS[0]);
+ });
+
+ test('should allow me to display active items', async ({ page }) => {
+ const todoItem = page.getByTestId('todo-item');
+ await page.getByTestId('todo-item').nth(1).getByRole('checkbox').check();
+
+ await checkNumberOfCompletedTodosInLocalStorage(page, 1);
+ await page.getByRole('link', { name: 'Active' }).click();
+ await expect(todoItem).toHaveCount(2);
+ await expect(todoItem).toHaveText([TODO_ITEMS[0], TODO_ITEMS[2]]);
+ });
+
+ test('should respect the back button', async ({ page }) => {
+ const todoItem = page.getByTestId('todo-item');
+ await page.getByTestId('todo-item').nth(1).getByRole('checkbox').check();
+
+ await checkNumberOfCompletedTodosInLocalStorage(page, 1);
+
+ await test.step('Showing all items', async () => {
+ await page.getByRole('link', { name: 'All' }).click();
+ await expect(todoItem).toHaveCount(3);
+ });
+
+ await test.step('Showing active items', async () => {
+ await page.getByRole('link', { name: 'Active' }).click();
+ });
+
+ await test.step('Showing completed items', async () => {
+ await page.getByRole('link', { name: 'Completed' }).click();
+ });
+
+ await expect(todoItem).toHaveCount(1);
+ await page.goBack();
+ await expect(todoItem).toHaveCount(2);
+ await page.goBack();
+ await expect(todoItem).toHaveCount(3);
+ });
+
+ test('should allow me to display completed items', async ({ page }) => {
+ await page.getByTestId('todo-item').nth(1).getByRole('checkbox').check();
+ await checkNumberOfCompletedTodosInLocalStorage(page, 1);
+ await page.getByRole('link', { name: 'Completed' }).click();
+ await expect(page.getByTestId('todo-item')).toHaveCount(1);
+ });
+
+ test('should allow me to display all items', async ({ page }) => {
+ await page.getByTestId('todo-item').nth(1).getByRole('checkbox').check();
+ await checkNumberOfCompletedTodosInLocalStorage(page, 1);
+ await page.getByRole('link', { name: 'Active' }).click();
+ await page.getByRole('link', { name: 'Completed' }).click();
+ await page.getByRole('link', { name: 'All' }).click();
+ await expect(page.getByTestId('todo-item')).toHaveCount(3);
+ });
+
+ test('should highlight the currently applied filter', async ({ page }) => {
+ await expect(page.getByRole('link', { name: 'All' })).toHaveClass('selected');
+
+ //create locators for active and completed links
+ const activeLink = page.getByRole('link', { name: 'Active' });
+ const completedLink = page.getByRole('link', { name: 'Completed' });
+ await activeLink.click();
+
+ // Page change - active items.
+ await expect(activeLink).toHaveClass('selected');
+ await completedLink.click();
+
+ // Page change - completed items.
+ await expect(completedLink).toHaveClass('selected');
+ });
+});
+
+async function createDefaultTodos(page: Page) {
+ // create a new todo locator
+ const newTodo = page.getByPlaceholder('What needs to be done?');
+
+ for (const item of TODO_ITEMS) {
+ await newTodo.fill(item);
+ await newTodo.press('Enter');
+ }
+}
+
+async function checkNumberOfTodosInLocalStorage(page: Page, expected: number) {
+ return await page.waitForFunction(e => {
+ return JSON.parse(localStorage['react-todos']).length === e;
+ }, expected);
+}
+
+async function checkNumberOfCompletedTodosInLocalStorage(page: Page, expected: number) {
+ return await page.waitForFunction(e => {
+ return JSON.parse(localStorage['react-todos']).filter((todo: any) => todo.completed).length === e;
+ }, expected);
+}
+
+async function checkTodosInLocalStorage(page: Page, title: string) {
+ return await page.waitForFunction(t => {
+ return JSON.parse(localStorage['react-todos']).map((todo: any) => todo.title).includes(t);
+ }, title);
+}
diff --git a/petclinic-frontend/tests/shoppage/shoppagetests.spec.ts b/petclinic-frontend/tests/shoppage/shoppagetests.spec.ts
new file mode 100644
index 000000000..9982c6395
--- /dev/null
+++ b/petclinic-frontend/tests/shoppage/shoppagetests.spec.ts
@@ -0,0 +1,22 @@
+import { test, expect } from '@playwright/test';
+
+test('Unlist Product', async ({ page }) => {
+//Authenticate as admin
+await page.goto('http://localhost:3000/users/login');
+await page.getByPlaceholder('Enter your email').fill('admin@admin.com');
+await page.getByPlaceholder('Enter your password').fill('pwd');
+await page.getByRole('button', { name: 'Login' }).click();
+
+await page.waitForURL('http://localhost:3000/home');
+
+await page.getByRole('link', { name: 'Shop' }).click();
+
+await page.getByRole('heading', { name: 'Fish Tank Heater' }).first().click();
+await page.getByRole('button', { name: 'Unlist Item' }).click();
+await page.getByRole('button', { name: 'Yes' }).click();
+
+await expect(page.getByRole('button', { name: 'List Item' })).toBeVisible();
+
+await page.close();
+
+});
\ No newline at end of file
From 6eeee3a71df501c5b42ce658905dd8b494d3ff23 Mon Sep 17 00:00:00 2001
From: Viktor Kuts
Date: Mon, 11 Nov 2024 17:15:23 -0500
Subject: [PATCH 03/14] PROD Product Details E2E Test (#1033)
**JIRA:** link to jira ticket
## Context:
What is the ticket about and why are we doing this change.
## Does this PR change the .vscode folder in petclinic-frontend?:
If the PR changes the .vscode folder, explain why in detail because it
should not.
Be sure to include cgerard321 as a reviewer.
**Reviewers need to check for any changes to the
.vscode folder and add a comment about it to their review
comments.**
## Changes
What are the various changes and what other modules do those changes
affect.
This can be bullet point or sentence format.
## Before and After UI (Required for UI-impacting PRs)
If this is a change to the UI, include before and after screenshots to
show the differences.
If this is a new UI feature, include screenshots to show reviewers what
it looks like.
## Dev notes (Optional)
Specific technical changes that should be noted
## Linked pull requests (Optional)
Pull request links
Co-authored-by: Jessy Gjerek <118135201+J91-cloud@users.noreply.github.com>
---
.../tests/productspage/viewproduct.spec.ts | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
create mode 100644 petclinic-frontend/tests/productspage/viewproduct.spec.ts
diff --git a/petclinic-frontend/tests/productspage/viewproduct.spec.ts b/petclinic-frontend/tests/productspage/viewproduct.spec.ts
new file mode 100644
index 000000000..c8db141ba
--- /dev/null
+++ b/petclinic-frontend/tests/productspage/viewproduct.spec.ts
@@ -0,0 +1,16 @@
+import { test, expect } from '@playwright/test';
+
+test('View Shop Product Title', async ({ page }) => {
+ await page.goto('http://localhost:3000/home');
+ await page.getByRole('link', { name: 'Login' }).click();
+ await page.getByPlaceholder('Enter your email').click();
+ await page.getByPlaceholder('Enter your email').fill('admin@admin.com');
+ await page.getByPlaceholder('Enter your password').click();
+ await page.getByPlaceholder('Enter your password').fill('pwd');
+ await page.getByRole('button', { name: 'Login' }).click();
+ await page.getByRole('link', { name: 'Shop' }).click();
+ await page.getByRole('heading', { name: 'Aquarium Filter' }).first().click();
+ await expect(
+ page.getByRole('heading', { name: 'Aquarium Filter', exact: true })
+ ).toContainText('Aquarium Filter');
+});
From 3dc11994053137eedff85496c3194d6363376505 Mon Sep 17 00:00:00 2001
From: Justin Morissette <123003289+Justin222993@users.noreply.github.com>
Date: Mon, 11 Nov 2024 17:23:55 -0500
Subject: [PATCH 04/14] Created the new Emailing Test (#1029)
# New test:
Check if we can send an email
Co-authored-by: Felix Allard <132389716+FelixAllard@users.noreply.github.com>
---
.../tests/emailing/emailingpagetests.spec.ts | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
create mode 100644 petclinic-frontend/tests/emailing/emailingpagetests.spec.ts
diff --git a/petclinic-frontend/tests/emailing/emailingpagetests.spec.ts b/petclinic-frontend/tests/emailing/emailingpagetests.spec.ts
new file mode 100644
index 000000000..52168fe91
--- /dev/null
+++ b/petclinic-frontend/tests/emailing/emailingpagetests.spec.ts
@@ -0,0 +1,25 @@
+import { test, expect } from '@playwright/test';
+
+test('Sending Email Test', async ({ page }) => {
+ await page.goto('http://localhost:3000/users/login');
+ await page.getByPlaceholder('Enter your email').click();
+ await page.getByPlaceholder('Enter your email').fill('admin@admin.com');
+ await page.getByPlaceholder('Enter your password').click();
+ await page.getByPlaceholder('Enter your password').fill('pwd');
+ await page.getByRole('button', { name: 'Login' }).click();
+ await page.getByRole('link', { name: 'Emails' }).click();
+ await page.getByRole('button', { name: 'Send Raw Email' }).click();
+ await page.locator('input[type="email"]').click();
+ await page.locator('input[type="email"]').fill('xilef992@gmail.com');
+ await page.locator('input[type="email"]').press('Tab');
+ await page.locator('input[type="text"]').fill('TestEmail');
+ await page.locator('input[type="text"]').press('Tab');
+ await page.locator('textarea').fill('This is a test email');
+ await page.getByRole('button', { name: 'Submit' }).click();
+ await expect(page.getByText('Status Code:')).toBeVisible();
+ await expect(page.locator('#root')).toContainText(
+ 'Message: Email sent successfully'
+ );
+
+ await page.close();
+});
From 63c48ff96d9f21bb026341774067e8754f8b3715 Mon Sep 17 00:00:00 2001
From: Jesse Bourassa <129144730+Jesse-Bourassa@users.noreply.github.com>
Date: Mon, 11 Nov 2024 17:32:08 -0500
Subject: [PATCH 05/14] Test Signup page (#1035)
---
.../tests/signuppage/signuppagetests.spec.ts | 29 +++++++++++++++++++
1 file changed, 29 insertions(+)
create mode 100644 petclinic-frontend/tests/signuppage/signuppagetests.spec.ts
diff --git a/petclinic-frontend/tests/signuppage/signuppagetests.spec.ts b/petclinic-frontend/tests/signuppage/signuppagetests.spec.ts
new file mode 100644
index 000000000..7597eec74
--- /dev/null
+++ b/petclinic-frontend/tests/signuppage/signuppagetests.spec.ts
@@ -0,0 +1,29 @@
+import { test, expect } from '@playwright/test';
+
+test('test', async ({ page }) => {
+await page.goto('http://localhost:3000/home');
+await page.getByRole('link', { name: 'Signup' }).click();
+await page.locator('input[name="firstName"]').click();
+await page.locator('input[name="firstName"]').fill('ew');
+await page.locator('input[name="lastName"]').click();
+await page.locator('input[name="lastName"]').fill('ew');
+await page.locator('input[name="address"]').click();
+await page.locator('input[name="address"]').fill('jesse');
+await page.locator('input[name="city"]').click();
+await page.locator('input[name="city"]').fill('stjean');
+await page.locator('input[name="province"]').click();
+await page.locator('input[name="province"]').fill('qc');
+await page.locator('input[name="telephone"]').click();
+await page.locator('input[name="telephone"]').fill('1234567890');
+await page.locator('input[name="username"]').click();
+await page.locator('input[name="username"]').fill('wewew');
+await page.locator('input[name="email"]').click();
+await page.locator('input[name="email"]').fill('wrongemail');
+await page.locator('input[name="password"]').click();
+await page.locator('input[name="password"]').press('CapsLock');
+await page.locator('input[name="password"]').fill('P');
+await page.locator('input[name="password"]').press('CapsLock');
+await page.locator('input[name="password"]').fill('Password12:');
+await page.getByRole('button', { name: 'Send Verification Email' }).click();
+await expect(page.locator('form')).toContainText('Invalid email format.');
+});
\ No newline at end of file
From e40256676bb74a0b9d0f274a62de9faf516f3d65 Mon Sep 17 00:00:00 2001
From: Debo
Date: Mon, 11 Nov 2024 17:40:06 -0500
Subject: [PATCH 06/14] created test for admin edit customer (#1031)
---
.../customerspage/customerspagetests.spec.ts | 34 +++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/petclinic-frontend/tests/customerspage/customerspagetests.spec.ts b/petclinic-frontend/tests/customerspage/customerspagetests.spec.ts
index 49732f270..4fa9d58ca 100644
--- a/petclinic-frontend/tests/customerspage/customerspagetests.spec.ts
+++ b/petclinic-frontend/tests/customerspage/customerspagetests.spec.ts
@@ -79,3 +79,37 @@ test('Get User By Id works and connected customer link works and right info', as
await page.close();
});
+
+test('Admin Edit Customer', async ({ page }) => {
+ await page.goto('http://localhost:3000/users/login');
+ await page.getByPlaceholder('Enter your email').click();
+ await page.getByPlaceholder('Enter your email').fill('admin@admin.com');
+ await page.getByPlaceholder('Enter your password').click();
+ await page.getByPlaceholder('Enter your password').fill('pwd');
+ await page.getByRole('button', { name: 'Login' }).click();
+ await page.getByRole('button', { name: 'Customers' }).click();
+ await page.getByRole('link', { name: 'Customers List' }).click();
+ await page.getByRole('link', { name: 'e6c7398e-8ac4-4e10-9ee0-' }).click();
+ await page.getByRole('button', { name: 'Edit Customer' }).click();
+ await page.locator('input[name="firstName"]').click();
+ await page.locator('input[name="firstName"]').fill('John');
+ await page.locator('input[name="lastName"]').click();
+ await page.locator('input[name="lastName"]').fill('Doe');
+ await page.locator('input[name="address"]').click();
+ await page.locator('input[name="address"]').fill('Baker Street 123');
+ await page.locator('input[name="city"]').click();
+ await page.locator('input[name="city"]').fill('Montreal');
+ await page.getByRole('combobox').selectOption('Quebec');
+ await page.locator('input[name="telephone"]').click();
+ await page.locator('input[name="telephone"]').fill('5144203239');
+ await page.getByRole('button', { name: 'Update' }).click();
+ await expect(page.locator('h2')).toContainText('Success!');
+ await expect(page.getByRole('paragraph')).toContainText('Customer has been successfully updated.');
+ await page.getByRole('button', { name: 'Close' }).click();
+ await expect(page.locator('#root')).toContainText('First Name: John');
+ await expect(page.locator('#root')).toContainText('Last Name: Doe');
+ await expect(page.locator('#root')).toContainText('City: Montreal');
+ await expect(page.locator('#root')).toContainText('Province: Quebec');
+ await expect(page.locator('#root')).toContainText('Telephone: 5144203239');
+ await page.close();
+});
From 9fdd381cb592b0363d89ee46878592e2ba498725 Mon Sep 17 00:00:00 2001
From: AlejandroBrnab <98438629+AlejandroBrnab@users.noreply.github.com>
Date: Mon, 11 Nov 2024 17:49:11 -0500
Subject: [PATCH 07/14] e2etest/VIST-AlejandroBernabe (#1036)
my test
---
.../tests/visitstestpage/addvisittest.spec.ts | 27 +++++++++++++++++++
1 file changed, 27 insertions(+)
create mode 100644 petclinic-frontend/tests/visitstestpage/addvisittest.spec.ts
diff --git a/petclinic-frontend/tests/visitstestpage/addvisittest.spec.ts b/petclinic-frontend/tests/visitstestpage/addvisittest.spec.ts
new file mode 100644
index 000000000..03a163c4e
--- /dev/null
+++ b/petclinic-frontend/tests/visitstestpage/addvisittest.spec.ts
@@ -0,0 +1,27 @@
+import { test, expect } from '@playwright/test';
+
+test('test', async ({ page }) => {
+ await page.goto('http://localhost:3000/users/login');
+ await page.getByPlaceholder('Enter your email').click();
+ await page.getByPlaceholder('Enter your email').fill('admin@admin.com');
+ await page.getByPlaceholder('Enter your password').click();
+ await page.getByPlaceholder('Enter your password').fill('pwd');
+ await page.getByRole('button', { name: 'Login' }).click();
+ await page.getByRole('link', { name: 'Visits' }).click();
+ await page.getByRole('button', { name: 'Make a Visit' }).click();
+ await page.locator('input[name="petId"]').click();
+ await page
+ .locator('input[name="petId"]')
+ .fill('0e4d8481-b611-4e52-baed-af16caa8bf8a');
+ await page.locator('input[name="visitStartDate"]').click();
+ await page.locator('input[name="visitStartDate"]').press('ArrowRight');
+ await page.locator('input[name="visitStartDate"]').press('ArrowRight');
+ await page.locator('input[name="visitStartDate"]').fill('2024-11-12T17:55');
+ await page.locator('input[name="description"]').click();
+ await page.locator('input[name="description"]').fill('doggo');
+ await page.locator('input[name="practitionerId"]').click();
+ await page
+ .locator('input[name="practitionerId"]')
+ .fill('69f85d2e-625b-11ee-8c99-0242ac120002');
+ await page.getByRole('button', { name: 'Add' }).click();
+});
From 30c076d5ef7bc5fa46fac2316c433ee433c1e604 Mon Sep 17 00:00:00 2001
From: Thomas <90119345+ThomasBedard@users.noreply.github.com>
Date: Mon, 11 Nov 2024 17:57:32 -0500
Subject: [PATCH 08/14] e2etest/PROD-Thomas (#1038)
## Context:
Made an e2e test for edit a product name
## Does this PR change the .vscode folder in petclinic-frontend?:
If the PR changes the .vscode folder, explain why in detail because it
should not.
it doesn't
---
.../tests/productspage/shoppagetests.spec.ts | 20 +++++++++++++++++++
test-results/.last-run.json | 4 ++++
2 files changed, 24 insertions(+)
create mode 100644 petclinic-frontend/tests/productspage/shoppagetests.spec.ts
create mode 100644 test-results/.last-run.json
diff --git a/petclinic-frontend/tests/productspage/shoppagetests.spec.ts b/petclinic-frontend/tests/productspage/shoppagetests.spec.ts
new file mode 100644
index 000000000..8d24cbf3a
--- /dev/null
+++ b/petclinic-frontend/tests/productspage/shoppagetests.spec.ts
@@ -0,0 +1,20 @@
+import { test, expect } from '@playwright/test';
+
+
+test('Admin View Vet Details from VetPage', async ({ page }) => {
+await page.goto('http://localhost:3000/users/login');
+await page.getByPlaceholder('Enter your email').click();
+await page.getByPlaceholder('Enter your email').fill('admin@admin.com');
+await page.getByPlaceholder('Enter your password').click();
+await page.getByPlaceholder('Enter your password').fill('pwd');
+await page.getByRole('button', { name: 'Login' }).click();
+await page.getByRole('link', { name: 'Shop' }).click();
+await page.getByRole('heading', { name: 'Fish Tank Heater' }).nth(1).click();
+await page.getByRole('button', { name: 'Edit' }).click();
+await page.getByLabel('Product Name:').click();
+await page.getByLabel('Product Name:').fill('Fish Tank');
+await page.getByLabel('Product Sale Price:').click();
+await page.getByLabel('Product Sale Price:').fill('19.99');
+await page.getByRole('button', { name: 'Update Product' }).click();
+await (expect(page.getByRole('heading', {name: 'Fish Tank'})).toBeVisible());
+});
\ No newline at end of file
diff --git a/test-results/.last-run.json b/test-results/.last-run.json
new file mode 100644
index 000000000..5fca3f84b
--- /dev/null
+++ b/test-results/.last-run.json
@@ -0,0 +1,4 @@
+{
+ "status": "failed",
+ "failedTests": []
+}
\ No newline at end of file
From 24ebe1a9e0856cb1fa0a868c700bcd7cb4d248a1 Mon Sep 17 00:00:00 2001
From: Aian Batoochirov <119423256+orell2j@users.noreply.github.com>
Date: Mon, 11 Nov 2024 18:24:47 -0500
Subject: [PATCH 09/14] e2etest/VETS-Aian: E2E testing add vet education
(#1047)
## Context:
Made an e2e test to add vet education and delete vet education
## Does this PR change the .vscode folder in petclinic-frontend?:
No
**Reviewers need to check for any changes to the
.vscode folder and add a comment about it to their review
comments.**
## Changes
Added e2e test files for adding and deleteing vet education
---
petclinic-frontend/playwright.config.ts | 24 +-
.../tests-examples/demo-todo-app.spec.ts | 437 ++++++++++++++++++
.../tests/tests-examples/e2e/test-1.spec.ts | 24 +
3 files changed, 473 insertions(+), 12 deletions(-)
create mode 100644 petclinic-frontend/tests/tests-examples/demo-todo-app.spec.ts
create mode 100644 petclinic-frontend/tests/tests-examples/e2e/test-1.spec.ts
diff --git a/petclinic-frontend/playwright.config.ts b/petclinic-frontend/playwright.config.ts
index 630689819..a05d8b5a1 100644
--- a/petclinic-frontend/playwright.config.ts
+++ b/petclinic-frontend/playwright.config.ts
@@ -34,10 +34,10 @@ export default defineConfig({
/* Configure projects for major browsers */
projects: [
- // {
- // name: 'chromium',
- // use: { ...devices['Desktop Chrome'] },
- // },
+ {
+ name: 'chromium',
+ use: { ...devices['Desktop Chrome'] },
+ },
{
name: 'firefox',
@@ -60,14 +60,14 @@ export default defineConfig({
// },
/* Test against branded browsers. */
- {
- name: 'Microsoft Edge',
- use: { ...devices['Desktop Edge'], channel: 'msedge' },
- },
- {
- name: 'Google Chrome',
- use: { ...devices['Desktop Chrome'], channel: 'chrome' },
- },
+ // {
+ // name: 'Microsoft Edge',
+ // use: { ...devices['Desktop Edge'], channel: 'msedge' },
+ // },
+ // {
+ // name: 'Google Chrome',
+ // use: { ...devices['Desktop Chrome'], channel: 'chrome' },
+ // },
],
/* Run your local dev server before starting the tests */
diff --git a/petclinic-frontend/tests/tests-examples/demo-todo-app.spec.ts b/petclinic-frontend/tests/tests-examples/demo-todo-app.spec.ts
new file mode 100644
index 000000000..8641cb5f5
--- /dev/null
+++ b/petclinic-frontend/tests/tests-examples/demo-todo-app.spec.ts
@@ -0,0 +1,437 @@
+import { test, expect, type Page } from '@playwright/test';
+
+test.beforeEach(async ({ page }) => {
+ await page.goto('https://demo.playwright.dev/todomvc');
+});
+
+const TODO_ITEMS = [
+ 'buy some cheese',
+ 'feed the cat',
+ 'book a doctors appointment'
+] as const;
+
+test.describe('New Todo', () => {
+ test('should allow me to add todo items', async ({ page }) => {
+ // create a new todo locator
+ const newTodo = page.getByPlaceholder('What needs to be done?');
+
+ // Create 1st todo.
+ await newTodo.fill(TODO_ITEMS[0]);
+ await newTodo.press('Enter');
+
+ // Make sure the list only has one todo item.
+ await expect(page.getByTestId('todo-title')).toHaveText([
+ TODO_ITEMS[0]
+ ]);
+
+ // Create 2nd todo.
+ await newTodo.fill(TODO_ITEMS[1]);
+ await newTodo.press('Enter');
+
+ // Make sure the list now has two todo items.
+ await expect(page.getByTestId('todo-title')).toHaveText([
+ TODO_ITEMS[0],
+ TODO_ITEMS[1]
+ ]);
+
+ await checkNumberOfTodosInLocalStorage(page, 2);
+ });
+
+ test('should clear text input field when an item is added', async ({ page }) => {
+ // create a new todo locator
+ const newTodo = page.getByPlaceholder('What needs to be done?');
+
+ // Create one todo item.
+ await newTodo.fill(TODO_ITEMS[0]);
+ await newTodo.press('Enter');
+
+ // Check that input is empty.
+ await expect(newTodo).toBeEmpty();
+ await checkNumberOfTodosInLocalStorage(page, 1);
+ });
+
+ test('should append new items to the bottom of the list', async ({ page }) => {
+ // Create 3 items.
+ await createDefaultTodos(page);
+
+ // create a todo count locator
+ const todoCount = page.getByTestId('todo-count')
+
+ // Check test using different methods.
+ await expect(page.getByText('3 items left')).toBeVisible();
+ await expect(todoCount).toHaveText('3 items left');
+ await expect(todoCount).toContainText('3');
+ await expect(todoCount).toHaveText(/3/);
+
+ // Check all items in one call.
+ await expect(page.getByTestId('todo-title')).toHaveText(TODO_ITEMS);
+ await checkNumberOfTodosInLocalStorage(page, 3);
+ });
+});
+
+test.describe('Mark all as completed', () => {
+ test.beforeEach(async ({ page }) => {
+ await createDefaultTodos(page);
+ await checkNumberOfTodosInLocalStorage(page, 3);
+ });
+
+ test.afterEach(async ({ page }) => {
+ await checkNumberOfTodosInLocalStorage(page, 3);
+ });
+
+ test('should allow me to mark all items as completed', async ({ page }) => {
+ // Complete all todos.
+ await page.getByLabel('Mark all as complete').check();
+
+ // Ensure all todos have 'completed' class.
+ await expect(page.getByTestId('todo-item')).toHaveClass(['completed', 'completed', 'completed']);
+ await checkNumberOfCompletedTodosInLocalStorage(page, 3);
+ });
+
+ test('should allow me to clear the complete state of all items', async ({ page }) => {
+ const toggleAll = page.getByLabel('Mark all as complete');
+ // Check and then immediately uncheck.
+ await toggleAll.check();
+ await toggleAll.uncheck();
+
+ // Should be no completed classes.
+ await expect(page.getByTestId('todo-item')).toHaveClass(['', '', '']);
+ });
+
+ test('complete all checkbox should update state when items are completed / cleared', async ({ page }) => {
+ const toggleAll = page.getByLabel('Mark all as complete');
+ await toggleAll.check();
+ await expect(toggleAll).toBeChecked();
+ await checkNumberOfCompletedTodosInLocalStorage(page, 3);
+
+ // Uncheck first todo.
+ const firstTodo = page.getByTestId('todo-item').nth(0);
+ await firstTodo.getByRole('checkbox').uncheck();
+
+ // Reuse toggleAll locator and make sure its not checked.
+ await expect(toggleAll).not.toBeChecked();
+
+ await firstTodo.getByRole('checkbox').check();
+ await checkNumberOfCompletedTodosInLocalStorage(page, 3);
+
+ // Assert the toggle all is checked again.
+ await expect(toggleAll).toBeChecked();
+ });
+});
+
+test.describe('Item', () => {
+
+ test('should allow me to mark items as complete', async ({ page }) => {
+ // create a new todo locator
+ const newTodo = page.getByPlaceholder('What needs to be done?');
+
+ // Create two items.
+ for (const item of TODO_ITEMS.slice(0, 2)) {
+ await newTodo.fill(item);
+ await newTodo.press('Enter');
+ }
+
+ // Check first item.
+ const firstTodo = page.getByTestId('todo-item').nth(0);
+ await firstTodo.getByRole('checkbox').check();
+ await expect(firstTodo).toHaveClass('completed');
+
+ // Check second item.
+ const secondTodo = page.getByTestId('todo-item').nth(1);
+ await expect(secondTodo).not.toHaveClass('completed');
+ await secondTodo.getByRole('checkbox').check();
+
+ // Assert completed class.
+ await expect(firstTodo).toHaveClass('completed');
+ await expect(secondTodo).toHaveClass('completed');
+ });
+
+ test('should allow me to un-mark items as complete', async ({ page }) => {
+ // create a new todo locator
+ const newTodo = page.getByPlaceholder('What needs to be done?');
+
+ // Create two items.
+ for (const item of TODO_ITEMS.slice(0, 2)) {
+ await newTodo.fill(item);
+ await newTodo.press('Enter');
+ }
+
+ const firstTodo = page.getByTestId('todo-item').nth(0);
+ const secondTodo = page.getByTestId('todo-item').nth(1);
+ const firstTodoCheckbox = firstTodo.getByRole('checkbox');
+
+ await firstTodoCheckbox.check();
+ await expect(firstTodo).toHaveClass('completed');
+ await expect(secondTodo).not.toHaveClass('completed');
+ await checkNumberOfCompletedTodosInLocalStorage(page, 1);
+
+ await firstTodoCheckbox.uncheck();
+ await expect(firstTodo).not.toHaveClass('completed');
+ await expect(secondTodo).not.toHaveClass('completed');
+ await checkNumberOfCompletedTodosInLocalStorage(page, 0);
+ });
+
+ test('should allow me to edit an item', async ({ page }) => {
+ await createDefaultTodos(page);
+
+ const todoItems = page.getByTestId('todo-item');
+ const secondTodo = todoItems.nth(1);
+ await secondTodo.dblclick();
+ await expect(secondTodo.getByRole('textbox', { name: 'Edit' })).toHaveValue(TODO_ITEMS[1]);
+ await secondTodo.getByRole('textbox', { name: 'Edit' }).fill('buy some sausages');
+ await secondTodo.getByRole('textbox', { name: 'Edit' }).press('Enter');
+
+ // Explicitly assert the new text value.
+ await expect(todoItems).toHaveText([
+ TODO_ITEMS[0],
+ 'buy some sausages',
+ TODO_ITEMS[2]
+ ]);
+ await checkTodosInLocalStorage(page, 'buy some sausages');
+ });
+});
+
+test.describe('Editing', () => {
+ test.beforeEach(async ({ page }) => {
+ await createDefaultTodos(page);
+ await checkNumberOfTodosInLocalStorage(page, 3);
+ });
+
+ test('should hide other controls when editing', async ({ page }) => {
+ const todoItem = page.getByTestId('todo-item').nth(1);
+ await todoItem.dblclick();
+ await expect(todoItem.getByRole('checkbox')).not.toBeVisible();
+ await expect(todoItem.locator('label', {
+ hasText: TODO_ITEMS[1],
+ })).not.toBeVisible();
+ await checkNumberOfTodosInLocalStorage(page, 3);
+ });
+
+ test('should save edits on blur', async ({ page }) => {
+ const todoItems = page.getByTestId('todo-item');
+ await todoItems.nth(1).dblclick();
+ await todoItems.nth(1).getByRole('textbox', { name: 'Edit' }).fill('buy some sausages');
+ await todoItems.nth(1).getByRole('textbox', { name: 'Edit' }).dispatchEvent('blur');
+
+ await expect(todoItems).toHaveText([
+ TODO_ITEMS[0],
+ 'buy some sausages',
+ TODO_ITEMS[2],
+ ]);
+ await checkTodosInLocalStorage(page, 'buy some sausages');
+ });
+
+ test('should trim entered text', async ({ page }) => {
+ const todoItems = page.getByTestId('todo-item');
+ await todoItems.nth(1).dblclick();
+ await todoItems.nth(1).getByRole('textbox', { name: 'Edit' }).fill(' buy some sausages ');
+ await todoItems.nth(1).getByRole('textbox', { name: 'Edit' }).press('Enter');
+
+ await expect(todoItems).toHaveText([
+ TODO_ITEMS[0],
+ 'buy some sausages',
+ TODO_ITEMS[2],
+ ]);
+ await checkTodosInLocalStorage(page, 'buy some sausages');
+ });
+
+ test('should remove the item if an empty text string was entered', async ({ page }) => {
+ const todoItems = page.getByTestId('todo-item');
+ await todoItems.nth(1).dblclick();
+ await todoItems.nth(1).getByRole('textbox', { name: 'Edit' }).fill('');
+ await todoItems.nth(1).getByRole('textbox', { name: 'Edit' }).press('Enter');
+
+ await expect(todoItems).toHaveText([
+ TODO_ITEMS[0],
+ TODO_ITEMS[2],
+ ]);
+ });
+
+ test('should cancel edits on escape', async ({ page }) => {
+ const todoItems = page.getByTestId('todo-item');
+ await todoItems.nth(1).dblclick();
+ await todoItems.nth(1).getByRole('textbox', { name: 'Edit' }).fill('buy some sausages');
+ await todoItems.nth(1).getByRole('textbox', { name: 'Edit' }).press('Escape');
+ await expect(todoItems).toHaveText(TODO_ITEMS);
+ });
+});
+
+test.describe('Counter', () => {
+ test('should display the current number of todo items', async ({ page }) => {
+ // create a new todo locator
+ const newTodo = page.getByPlaceholder('What needs to be done?');
+
+ // create a todo count locator
+ const todoCount = page.getByTestId('todo-count')
+
+ await newTodo.fill(TODO_ITEMS[0]);
+ await newTodo.press('Enter');
+
+ await expect(todoCount).toContainText('1');
+
+ await newTodo.fill(TODO_ITEMS[1]);
+ await newTodo.press('Enter');
+ await expect(todoCount).toContainText('2');
+
+ await checkNumberOfTodosInLocalStorage(page, 2);
+ });
+});
+
+test.describe('Clear completed button', () => {
+ test.beforeEach(async ({ page }) => {
+ await createDefaultTodos(page);
+ });
+
+ test('should display the correct text', async ({ page }) => {
+ await page.locator('.todo-list li .toggle').first().check();
+ await expect(page.getByRole('button', { name: 'Clear completed' })).toBeVisible();
+ });
+
+ test('should remove completed items when clicked', async ({ page }) => {
+ const todoItems = page.getByTestId('todo-item');
+ await todoItems.nth(1).getByRole('checkbox').check();
+ await page.getByRole('button', { name: 'Clear completed' }).click();
+ await expect(todoItems).toHaveCount(2);
+ await expect(todoItems).toHaveText([TODO_ITEMS[0], TODO_ITEMS[2]]);
+ });
+
+ test('should be hidden when there are no items that are completed', async ({ page }) => {
+ await page.locator('.todo-list li .toggle').first().check();
+ await page.getByRole('button', { name: 'Clear completed' }).click();
+ await expect(page.getByRole('button', { name: 'Clear completed' })).toBeHidden();
+ });
+});
+
+test.describe('Persistence', () => {
+ test('should persist its data', async ({ page }) => {
+ // create a new todo locator
+ const newTodo = page.getByPlaceholder('What needs to be done?');
+
+ for (const item of TODO_ITEMS.slice(0, 2)) {
+ await newTodo.fill(item);
+ await newTodo.press('Enter');
+ }
+
+ const todoItems = page.getByTestId('todo-item');
+ const firstTodoCheck = todoItems.nth(0).getByRole('checkbox');
+ await firstTodoCheck.check();
+ await expect(todoItems).toHaveText([TODO_ITEMS[0], TODO_ITEMS[1]]);
+ await expect(firstTodoCheck).toBeChecked();
+ await expect(todoItems).toHaveClass(['completed', '']);
+
+ // Ensure there is 1 completed item.
+ await checkNumberOfCompletedTodosInLocalStorage(page, 1);
+
+ // Now reload.
+ await page.reload();
+ await expect(todoItems).toHaveText([TODO_ITEMS[0], TODO_ITEMS[1]]);
+ await expect(firstTodoCheck).toBeChecked();
+ await expect(todoItems).toHaveClass(['completed', '']);
+ });
+});
+
+test.describe('Routing', () => {
+ test.beforeEach(async ({ page }) => {
+ await createDefaultTodos(page);
+ // make sure the app had a chance to save updated todos in storage
+ // before navigating to a new view, otherwise the items can get lost :(
+ // in some frameworks like Durandal
+ await checkTodosInLocalStorage(page, TODO_ITEMS[0]);
+ });
+
+ test('should allow me to display active items', async ({ page }) => {
+ const todoItem = page.getByTestId('todo-item');
+ await page.getByTestId('todo-item').nth(1).getByRole('checkbox').check();
+
+ await checkNumberOfCompletedTodosInLocalStorage(page, 1);
+ await page.getByRole('link', { name: 'Active' }).click();
+ await expect(todoItem).toHaveCount(2);
+ await expect(todoItem).toHaveText([TODO_ITEMS[0], TODO_ITEMS[2]]);
+ });
+
+ test('should respect the back button', async ({ page }) => {
+ const todoItem = page.getByTestId('todo-item');
+ await page.getByTestId('todo-item').nth(1).getByRole('checkbox').check();
+
+ await checkNumberOfCompletedTodosInLocalStorage(page, 1);
+
+ await test.step('Showing all items', async () => {
+ await page.getByRole('link', { name: 'All' }).click();
+ await expect(todoItem).toHaveCount(3);
+ });
+
+ await test.step('Showing active items', async () => {
+ await page.getByRole('link', { name: 'Active' }).click();
+ });
+
+ await test.step('Showing completed items', async () => {
+ await page.getByRole('link', { name: 'Completed' }).click();
+ });
+
+ await expect(todoItem).toHaveCount(1);
+ await page.goBack();
+ await expect(todoItem).toHaveCount(2);
+ await page.goBack();
+ await expect(todoItem).toHaveCount(3);
+ });
+
+ test('should allow me to display completed items', async ({ page }) => {
+ await page.getByTestId('todo-item').nth(1).getByRole('checkbox').check();
+ await checkNumberOfCompletedTodosInLocalStorage(page, 1);
+ await page.getByRole('link', { name: 'Completed' }).click();
+ await expect(page.getByTestId('todo-item')).toHaveCount(1);
+ });
+
+ test('should allow me to display all items', async ({ page }) => {
+ await page.getByTestId('todo-item').nth(1).getByRole('checkbox').check();
+ await checkNumberOfCompletedTodosInLocalStorage(page, 1);
+ await page.getByRole('link', { name: 'Active' }).click();
+ await page.getByRole('link', { name: 'Completed' }).click();
+ await page.getByRole('link', { name: 'All' }).click();
+ await expect(page.getByTestId('todo-item')).toHaveCount(3);
+ });
+
+ test('should highlight the currently applied filter', async ({ page }) => {
+ await expect(page.getByRole('link', { name: 'All' })).toHaveClass('selected');
+
+ //create locators for active and completed links
+ const activeLink = page.getByRole('link', { name: 'Active' });
+ const completedLink = page.getByRole('link', { name: 'Completed' });
+ await activeLink.click();
+
+ // Page change - active items.
+ await expect(activeLink).toHaveClass('selected');
+ await completedLink.click();
+
+ // Page change - completed items.
+ await expect(completedLink).toHaveClass('selected');
+ });
+});
+
+async function createDefaultTodos(page: Page) {
+ // create a new todo locator
+ const newTodo = page.getByPlaceholder('What needs to be done?');
+
+ for (const item of TODO_ITEMS) {
+ await newTodo.fill(item);
+ await newTodo.press('Enter');
+ }
+}
+
+async function checkNumberOfTodosInLocalStorage(page: Page, expected: number) {
+ return await page.waitForFunction(e => {
+ return JSON.parse(localStorage['react-todos']).length === e;
+ }, expected);
+}
+
+async function checkNumberOfCompletedTodosInLocalStorage(page: Page, expected: number) {
+ return await page.waitForFunction(e => {
+ return JSON.parse(localStorage['react-todos']).filter((todo: any) => todo.completed).length === e;
+ }, expected);
+}
+
+async function checkTodosInLocalStorage(page: Page, title: string) {
+ return await page.waitForFunction(t => {
+ return JSON.parse(localStorage['react-todos']).map((todo: any) => todo.title).includes(t);
+ }, title);
+}
diff --git a/petclinic-frontend/tests/tests-examples/e2e/test-1.spec.ts b/petclinic-frontend/tests/tests-examples/e2e/test-1.spec.ts
new file mode 100644
index 000000000..3f3e24712
--- /dev/null
+++ b/petclinic-frontend/tests/tests-examples/e2e/test-1.spec.ts
@@ -0,0 +1,24 @@
+import { test, expect } from '@playwright/test';
+
+test('test', async ({ page }) => {
+ await page.goto('http://localhost:3000/users/login');
+ await page.getByPlaceholder('Enter your email').click();
+ await page.getByPlaceholder('Enter your email').fill('admin@admin.com');
+ await page.getByPlaceholder('Enter your password').click();
+ await page.getByPlaceholder('Enter your password').fill('pwd');
+ await page.getByRole('button', { name: 'Login' }).click();
+ await page.getByRole('link', { name: 'Veterinarians' }).click();
+ await page.locator('.card-image').first().click();
+ await page.getByRole('button', { name: 'Add Education' }).nth(1).click();
+ await page.getByRole('button', { name: 'Add Education' }).nth(1).click();
+ await page.locator('div').filter({ hasText: /^School Name$/ }).getByRole('textbox').click();
+ await page.locator('div').filter({ hasText: /^School Name$/ }).getByRole('textbox').fill('Champlain College');
+ await page.locator('div').filter({ hasText: /^Degree$/ }).getByRole('textbox').click();
+ await page.locator('div').filter({ hasText: /^Degree$/ }).getByRole('textbox').fill('Cegep');
+ await page.locator('div').filter({ hasText: /^Field of Study$/ }).getByRole('textbox').click();
+ await page.locator('div').filter({ hasText: /^Field of Study$/ }).getByRole('textbox').fill('Computer Science');
+ await page.locator('div').filter({ hasText: /^Start Date$/ }).getByRole('textbox').fill('2021-08-23');
+ await page.locator('div').filter({ hasText: /^End Date$/ }).getByRole('textbox').fill('2025-05-16');
+ await page.getByRole('dialog').getByRole('button', { name: 'Add Education' }).click();
+ await page.getByRole('button', { name: 'Delete Education' }).nth(2).click();
+});
\ No newline at end of file
From d9af6ffdb8e039f741ebd435ec13c643bb9dd9e9 Mon Sep 17 00:00:00 2001
From: Vinicius Velozo de Sousa <77692089+vinivelozo@users.noreply.github.com>
Date: Mon, 11 Nov 2024 18:59:40 -0500
Subject: [PATCH 10/14] Test for search by description (#1039)
Test for search by description (INVT)
---
.../FindInventoryByDescription.spec.ts | 15 +++++++++++++++
petclinic-frontend/tests/test-1.spec.ts | 5 +++++
2 files changed, 20 insertions(+)
create mode 100644 petclinic-frontend/tests/inventoriespage/FindInventoryByDescription.spec.ts
create mode 100644 petclinic-frontend/tests/test-1.spec.ts
diff --git a/petclinic-frontend/tests/inventoriespage/FindInventoryByDescription.spec.ts b/petclinic-frontend/tests/inventoriespage/FindInventoryByDescription.spec.ts
new file mode 100644
index 000000000..e7a18cda9
--- /dev/null
+++ b/petclinic-frontend/tests/inventoriespage/FindInventoryByDescription.spec.ts
@@ -0,0 +1,15 @@
+import { test, expect } from '@playwright/test';
+
+test('test', async ({ page }) => {
+ await page.goto('http://localhost:3000/users/login');
+ await page.getByPlaceholder('Enter your email').click();
+ await page.getByPlaceholder('Enter your email').fill('admin@admin.com');
+ await page.getByPlaceholder('Enter your password').click();
+ await page.getByPlaceholder('Enter your password').fill('pwd');
+ await page.getByRole('button', { name: 'Login' }).click();
+ await page.getByRole('link', { name: 'Inventories' }).click();
+ await page.getByRole('textbox').nth(1).click();
+ await page.getByRole('textbox').nth(1).fill('tools');
+ await page.getByRole('button', { name: 'Search' }).click();
+ await expect(page.getByText('Tools for performing surgical')).toBeVisible();
+});
\ No newline at end of file
diff --git a/petclinic-frontend/tests/test-1.spec.ts b/petclinic-frontend/tests/test-1.spec.ts
new file mode 100644
index 000000000..5b3d48cfd
--- /dev/null
+++ b/petclinic-frontend/tests/test-1.spec.ts
@@ -0,0 +1,5 @@
+import { test, expect } from '@playwright/test';
+
+test('test', async ({ page }) => {
+ // Recording...
+});
\ No newline at end of file
From d43ae71913d35aae15838c05772a2b1676497f0d Mon Sep 17 00:00:00 2001
From: Carlos Alvarado <142922516+Carlos-123321@users.noreply.github.com>
Date: Mon, 11 Nov 2024 19:50:48 -0500
Subject: [PATCH 11/14] Test for updating an inventory (#1051)
**JIRA:** link to jira ticket
## Context:
Added a test which checks that if an inventory is updated correctly, it
should display a message saying "Inventory updated successfully".
---
.../inventoriespage/updateInventory.spec.ts | 24 +++++++++++++++++++
1 file changed, 24 insertions(+)
create mode 100644 petclinic-frontend/tests/inventoriespage/updateInventory.spec.ts
diff --git a/petclinic-frontend/tests/inventoriespage/updateInventory.spec.ts b/petclinic-frontend/tests/inventoriespage/updateInventory.spec.ts
new file mode 100644
index 000000000..33f91eaa0
--- /dev/null
+++ b/petclinic-frontend/tests/inventoriespage/updateInventory.spec.ts
@@ -0,0 +1,24 @@
+import { test, expect } from '@playwright/test';
+
+test('Update Inventory', async ({ page }) => {
+
+ await page.goto('http://localhost:3000/users/login');
+ await page.getByPlaceholder('Enter your email').click();
+ await page.getByPlaceholder('Enter your email').fill('admin@admin.com');
+ await page.getByPlaceholder('Enter your email').press('Tab');
+ await page.getByPlaceholder('Enter your password').fill('pwd');
+ await page.getByPlaceholder('Enter your password').press('Enter');
+ await page.getByRole('button', { name: 'Login' }).click();
+ await page.getByRole('link', { name: 'Inventories' }).click();
+ await page.locator('div').filter({ hasText: /^Carlos3 Type: EquipmentMedical equipment for surgery$/ }).locator('[id="_cardMenu_cob55_1"]').click();
+ await page.getByRole('button', { name: 'Edit' }).click(); await page.getByPlaceholder('Inventory Name').click();
+ await page.getByPlaceholder('Inventory Name').fill('');
+ await page.getByPlaceholder('Inventory Name').press('CapsLock');
+ await page.getByPlaceholder('Inventory Name').fill('M');
+ await page.getByPlaceholder('Inventory Name').press('CapsLock');
+ await page.getByPlaceholder('Inventory Name').fill('Medical');
+ await page.getByRole('button', { name: 'Update' }).click();
+ await expect(page.getByText('Inventory updated successfully').first()).toBeVisible();
+ await page.goto('http://localhost:3000/inventories');
+
+});
\ No newline at end of file
From f6ce8c5d9e5e3e240d7f02059be13fe92d974835 Mon Sep 17 00:00:00 2001
From: Zakaria_ <135060272+Zako563@users.noreply.github.com>
Date: Mon, 11 Nov 2024 21:20:32 -0500
Subject: [PATCH 12/14] E2etest/vist zakaria (#1052)
**JIRA:** link to jira ticket
## Context:
What is the ticket about and why are we doing this change.
## Does this PR change the .vscode folder in petclinic-frontend?:
If the PR changes the .vscode folder, explain why in detail because it
should not.
Be sure to include cgerard321 as a reviewer.
**Reviewers need to check for any changes to the
.vscode folder and add a comment about it to their review
comments.**
## Changes
Test for add
What are the various changes and what other modules do those changes
affect.
This can be bullet point or sentence format.
## Before and After UI (Required for UI-impacting PRs)
If this is a change to the UI, include before and after screenshots to
show the differences.
If this is a new UI feature, include screenshots to show reviewers what
it looks like.
## Dev notes (Optional)
Specific technical changes that should be noted
## Linked pull requests (Optional)
Pull request links
---------
Co-authored-by: Zakaria_ <135060272+tramway23@users.noreply.github.com>
---
.../tests/AddEmergencyVisit(Zakaria).spec.ts | 32 +++++++++++++++++++
1 file changed, 32 insertions(+)
create mode 100644 petclinic-frontend/tests/AddEmergencyVisit(Zakaria).spec.ts
diff --git a/petclinic-frontend/tests/AddEmergencyVisit(Zakaria).spec.ts b/petclinic-frontend/tests/AddEmergencyVisit(Zakaria).spec.ts
new file mode 100644
index 000000000..2a27db282
--- /dev/null
+++ b/petclinic-frontend/tests/AddEmergencyVisit(Zakaria).spec.ts
@@ -0,0 +1,32 @@
+import { test, expect } from '@playwright/test';
+
+test('test', async ({ page }) => {
+ //test
+ await page.goto('http://localhost:3000/users/login');
+ await page.getByPlaceholder('Enter your email').click();
+ await page.getByPlaceholder('Enter your email').fill('betty@email.com');
+ await page.getByPlaceholder('Enter your password').click();
+ await page.getByPlaceholder('Enter your password').fill('pwd');
+ await page.getByRole('button', { name: 'Login' }).click();
+ await page.getByRole('link', { name: 'Emergency' }).click();
+ await page.getByRole('button', { name: 'Create Emergency visit' }).click();
+ await page.locator('input[name="petName"]').click();
+ await page.locator('input[name="petName"]').fill('ham');
+ await page.locator('textarea[name="description"]').click();
+ await page.locator('textarea[name="description"]').fill('c');
+ await page.getByText('c', { exact: true }).fill('cast');
+ await page.locator('input[name="emergencyType"]').click();
+ await page.locator('input[name="emergencyType"]').fill('death');
+ await page.getByRole('combobox').selectOption('MEDIUM');
+ await page.locator('input[name="petId"]').click();
+ await page.locator('input[name="petId"]').click();
+ await page
+ .locator('input[name="petId"]')
+ .fill('ecb109cd-57ea-4b85-b51e-99751fd1c349');
+ await page.locator('input[name="practitionerId"]').click();
+ await page.locator('input[name="practitionerId"]').click();
+ await page
+ .locator('input[name="practitionerId"]')
+ .fill('69f85d2e-625b-11ee-8c99-0242ac120002');
+ await page.getByRole('button', { name: 'Submit Emergency' }).click();
+});
From b9b1598dcfdc20843ac4780af00d3e38ce5c569c Mon Sep 17 00:00:00 2001
From: Sunveer <142905066+Sunveerg@users.noreply.github.com>
Date: Mon, 11 Nov 2024 23:27:37 -0500
Subject: [PATCH 13/14] Test for search product by name (#1041)
Test in front-end for search by inventory name.
---
.../searchInventoryByName.spec.ts | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
create mode 100644 petclinic-frontend/tests/inventoriespage/searchInventoryByName.spec.ts
diff --git a/petclinic-frontend/tests/inventoriespage/searchInventoryByName.spec.ts b/petclinic-frontend/tests/inventoriespage/searchInventoryByName.spec.ts
new file mode 100644
index 000000000..652f2de65
--- /dev/null
+++ b/petclinic-frontend/tests/inventoriespage/searchInventoryByName.spec.ts
@@ -0,0 +1,18 @@
+import { test, expect } from '@playwright/test';
+
+test('test', async ({ page }) => {
+ await page.goto('http://localhost:3000/users/login');
+ await page.getByPlaceholder('Enter your email').click();
+ await page.getByPlaceholder('Enter your email').fill('admin@admin.com');
+ await page.getByPlaceholder('Enter your password').click();
+ await page.getByPlaceholder('Enter your password').fill('pwd');
+ await page.getByRole('button', { name: 'Login' }).click();
+ await page.getByRole('link', { name: 'Inventories' }).click();
+ await page.getByRole('textbox').first().click();
+ await page.getByRole('textbox').first().press('CapsLock');
+ await page.getByRole('textbox').first().fill('M');
+ await page.getByRole('textbox').first().press('CapsLock');
+ await page.getByRole('cell', { name: 'M', exact: true }).getByRole('textbox').fill('Medical');
+ await page.getByRole('button', { name: 'Search' }).click();
+ await expect(page.getByText('Medical equipment', { exact: true })).toBeVisible();
+});
\ No newline at end of file
From 81fbcf0d434e28038182be38aaa4fc1c1642dd78 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zachary=20Leli=C3=A8vre?=
<93009892+ZacharyLelievre@users.noreply.github.com>
Date: Tue, 12 Nov 2024 11:24:57 -0500
Subject: [PATCH 14/14] e2etest/PROD-Zachary (#1056)
**JIRA:** [Link to JIRA ticket]
## Context:
This ticket focuses on adding a test to ensure that the review filter
works correctly when users set a minimum rating equal to or higher than
the maximum rating. The test verifies that an error message is displayed
if this condition is met.
## Does this PR change the .vscode folder in petclinic-frontend?:
No changes were made to the `.vscode` folder. Reviewers, please confirm
that no unintentional changes were made to this folder.
**Reviewers need to check for any changes to the
.vscode folder and add a comment about it to their review
comments.**
## Changes
- Added validation to the review filter for minimum and maximum star
ratings.
---
.../tests/productspage/filterbyreview.spec.ts | 26 +++++++++++++++++++
1 file changed, 26 insertions(+)
create mode 100644 petclinic-frontend/tests/productspage/filterbyreview.spec.ts
diff --git a/petclinic-frontend/tests/productspage/filterbyreview.spec.ts b/petclinic-frontend/tests/productspage/filterbyreview.spec.ts
new file mode 100644
index 000000000..938486607
--- /dev/null
+++ b/petclinic-frontend/tests/productspage/filterbyreview.spec.ts
@@ -0,0 +1,26 @@
+import { test, expect } from '@playwright/test';
+
+ test('test', async ({ page }) => {
+ await page.goto('http://localhost:3000/users/login');
+ await page.getByPlaceholder('Enter your email').click();
+ await page.getByPlaceholder('Enter your email').fill('betty@email.com');
+ await page.getByPlaceholder('Enter your password').click();
+ await page.getByPlaceholder('Enter your password').fill('pwd');
+ await page.getByRole('button', { name: 'Login' }).click();
+ await page.getByRole('link', { name: 'Visits' }).click();
+ await page.getByRole('button', { name: 'Leave a Review' }).click();
+ await page.getByRole('spinbutton').click();
+ await page.getByRole('spinbutton').fill('5');
+ await page.locator('input[name="reviewerName"]').click();
+ await page.locator('input[name="reviewerName"]').press('CapsLock');
+ await page.locator('input[name="reviewerName"]').fill('B');
+ await page.locator('input[name="reviewerName"]').press('CapsLock');
+ await page.locator('input[name="reviewerName"]').fill('Betty');
+ await page.locator('textarea[name="review"]').click();
+ await page.locator('textarea[name="review"]').press('CapsLock');
+ await page.locator('textarea[name="review"]').fill('V');
+ await page.locator('textarea[name="review"]').press('CapsLock');
+ await page.getByText('V', { exact: true }).fill('Very good!');
+ await page.getByRole('button', { name: 'Submit Review' }).click();
+
+ });
\ No newline at end of file