From 4343a060c350de07d3c4c81403590551e2e5acdd Mon Sep 17 00:00:00 2001 From: ZIhan Date: Thu, 19 Sep 2024 14:16:25 +0800 Subject: [PATCH] Generate test script by LLM --- test1/playwright.config.ts | 2 +- test3/images/image-4.png | Bin 0 -> 90878 bytes test3/playwright.config.ts | 8 +- test3/prompts_record.md | 35 ++++++- test3/tests/llm0.spec.ts | 140 +++++++++++++++++++++++++ test3/tests/llm1.spec.ts | 155 ++++++++++++++++++++++++++++ test3/tests/llm2.spec.ts | 178 ++++++++++++++++++++++++++++++++ test3/tests/llm3.spec.ts | 185 +++++++++++++++++++++++++++++++++ test3/tests/llm4.spec.ts | 205 +++++++++++++++++++++++++++++++++++++ 9 files changed, 903 insertions(+), 5 deletions(-) create mode 100644 test3/images/image-4.png create mode 100644 test3/tests/llm0.spec.ts create mode 100644 test3/tests/llm1.spec.ts create mode 100644 test3/tests/llm2.spec.ts create mode 100644 test3/tests/llm3.spec.ts create mode 100644 test3/tests/llm4.spec.ts diff --git a/test1/playwright.config.ts b/test1/playwright.config.ts index a505b69..523748e 100644 --- a/test1/playwright.config.ts +++ b/test1/playwright.config.ts @@ -22,7 +22,7 @@ export default defineConfig({ /* Fail the build on CI if you accidentally left test.only in the source code. */ forbidOnly: !!process.env.CI, /* Retry on CI only */ - retries: process.env.CI ? 2 :2, + retries: process.env.CI ? 2 :0, /* Opt out of parallel tests on CI. */ workers: process.env.CI ? 1 : undefined, /* Reporter to use. See https://playwright.dev/docs/test-reporters */ diff --git a/test3/images/image-4.png b/test3/images/image-4.png new file mode 100644 index 0000000000000000000000000000000000000000..e7ed1177a88514950a683828ffab64fff0d8903a GIT binary patch literal 90878 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⁡5f3(($$(|pFvy<)*$@NnGdY6HpD8c*|& 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 literal 0 HcmV?d00001 diff --git a/test3/playwright.config.ts b/test3/playwright.config.ts index 81986e6..01568d0 100644 --- a/test3/playwright.config.ts +++ b/test3/playwright.config.ts @@ -12,6 +12,10 @@ import { defineConfig, devices } from '@playwright/test'; */ export default defineConfig({ testDir: './tests', + testMatch:[ + 'basic.spec.ts', + 'llm4.spec.ts' + ], /* Run tests in files in parallel */ fullyParallel: true, /* Fail the build on CI if you accidentally left test.only in the source code. */ @@ -39,7 +43,7 @@ export default defineConfig({ use: { ...devices['Desktop Chrome'] }, }, - { + /*{ name: 'firefox', use: { ...devices['Desktop Firefox'] }, }, @@ -47,7 +51,7 @@ export default defineConfig({ { name: 'webkit', use: { ...devices['Desktop Safari'] }, - }, + },*/ /* Test against mobile viewports. */ // { diff --git a/test3/prompts_record.md b/test3/prompts_record.md index 4cc3858..f70c8a1 100644 --- a/test3/prompts_record.md +++ b/test3/prompts_record.md @@ -1,4 +1,4 @@ -## P0 Prompt 1 +## P0 Prompt 0 我直接把「飲料訂購系統.pdf」塞給claude ### 成果 ![alt text](./images/image.png) @@ -10,7 +10,7 @@ bug: 飲料訂購那些資訊需要塞成一個橫排的表格,如pdf中圖3-1 不算bug的bug: 題目會給一個csv,但我沒有丟csv給claude,所以他在js那邊模擬了一個csv,很有想法 -## P0 Prompt 2 +## P0 Prompt 1 按照成果1的bug去修,我丟給他以下截圖給的Prompt為「我希望飲料訂購部分的排版跟這個一樣,並重新給我完整的html5,css,js檔案」 ![alt text](./images/image-2.png) @@ -25,3 +25,34 @@ bug: 飲料訂購那些資訊需要塞成一個橫排的表格,如pdf中圖3-1 ### 成果 跟上一個成果沒什麼不一樣 +### p2 Prompt 0 +我把「html5,css,js」丟給Claude,並且給他這樣的Prompt:「現在要用playwright進行端對端測試,針對每一個需求進行最詳盡的測試並且給我,預設使用typerscript 去生成playwright腳本,對於每個測試腳本要註解是測試的需求是哪個,並且盡量用data-testid和aria-label去做selector,給我完整的測試腳本」 + +### 成果 +Claude給了這些測試腳本,有些部分測試會是爛掉的,像是「溫度選項正確」、「甜度選項正確」、「結帳流程」,因此我讓Claude一個一個慢慢改 + +![alt text](./images/image-4.png) + +### p2 Prompt 1 (修改「溫度選項正確」) +Prompt:「溫度選項正確這一個測試是錯的,我要好好的打開combobox,去看裡面的東西是不是為visible的,請幫我修改這個測試」 + +### 成果 +「溫度選項正確」是對的 + +### p2 Prompt 2(修改「甜度選項正確」) +Prompt:「甜度選項正確這一個測試是錯的,我要好好的打開combobox,去看裡面的東西是不是為visible的,請幫我修改這個測試」 + +### 成果 +「甜度選項正確」是錯的,他根本沒有好好的打開combobox接著check裡面的東西 + +### p2 Prompt 3(修改「甜度選項正確」) +在check visible的時候出現問題,請麻煩改正它 + +### 成果 +「溫度選項正確」是對的 + +### p2 Prompt 4修改「結帳流程顯示訂單摘要並清空訂購清單」 +最後一個測試:「結帳流程顯示訂單摘要並清空訂購清單」也是錯的,在checkoutButton.click時出了問題,請修他 + +### 成果 +「結帳流程顯示訂單摘要並清空訂購清單」對了,可喜可賀 diff --git a/test3/tests/llm0.spec.ts b/test3/tests/llm0.spec.ts new file mode 100644 index 0000000..bff0dfa --- /dev/null +++ b/test3/tests/llm0.spec.ts @@ -0,0 +1,140 @@ +import { test, expect } from '@playwright/test'; + +test.describe('飲料訂購系統', () => { + test.beforeEach(async ({ page }) => { + await page.goto('http://localhost:8080'); // 根據需要調整 URL + }); + + // 需求 1: 使用者界面元素 + test('使用者界面元素存在且正確佈局', async ({ page }) => { + // 檢查主要元素是否存在 + await expect(page.getByRole('heading', { name: '來點什麼...' })).toBeVisible(); + await expect(page.getByTestId('price-display')).toBeVisible(); + await expect(page.getByTestId('total-display')).toBeVisible(); + await expect(page.getByRole('button', { name: '確認' })).toBeVisible(); + + // 檢查下拉式選單元素 + await expect(page.getByRole('combobox', { name: '品名' })).toBeVisible(); + await expect(page.getByRole('combobox', { name: '容量' })).toBeVisible(); + await expect(page.getByRole('combobox', { name: '溫度' })).toBeVisible(); + await expect(page.getByRole('combobox', { name: '甜度' })).toBeVisible(); + + // 檢查輸入元素 + await expect(page.getByRole('spinbutton', { name: '數量' })).toBeVisible(); + await expect(page.getByRole('textbox', { name: '訂購人' })).toBeVisible(); + }); + + // 需求 2a, 2b, 2c: 品名和容量選項 + test('品名和容量選項正確填充', async ({ page }) => { + const itemSelect = page.getByRole('combobox', { name: '品名' }); + await expect(itemSelect).toHaveCount(1); + + const itemOptions = await itemSelect.getByRole('option').all(); + expect(itemOptions.length).toBeGreaterThan(0); + expect(itemOptions.length).toBeLessThanOrEqual(10); + + // 選擇第一個品項並檢查容量選項 + await itemSelect.selectOption({ index: 0 }); + const sizeSelect = page.getByRole('combobox', { name: '容量' }); + const sizeOptions = await sizeSelect.getByRole('option').all(); + expect(sizeOptions.length).toBeGreaterThan(0); + }); + + // 需求 2d, 3: 價格和總金額計算 + test('價格和總金額計算正確', async ({ page }) => { + const itemSelect = page.getByRole('combobox', { name: '品名' }); + const sizeSelect = page.getByRole('combobox', { name: '容量' }); + const quantityInput = page.getByRole('spinbutton', { name: '數量' }); + const priceDisplay = page.getByTestId('price-display'); + const totalDisplay = page.getByTestId('total-display'); + + await itemSelect.selectOption({ index: 0 }); + await sizeSelect.selectOption({ index: 0 }); + await expect(priceDisplay).not.toHaveText('0'); + + await quantityInput.fill('2'); + const price = await priceDisplay.innerText(); + const expectedTotal = (parseInt(price) * 2).toString(); + await expect(totalDisplay).toHaveText(expectedTotal); + }); + + // 需求 4: 溫度選項 + test('溫度選項正確', async ({ page }) => { + const tempSelect = page.getByRole('combobox', { name: '溫度' }); + const options = ['熱', '全冰', '少冰', '去冰']; + for (const option of options) { + await expect(tempSelect.getByText(option)).toBeVisible(); + } + }); + + // 需求 5: 甜度選項 + test('甜度選項正確', async ({ page }) => { + const sweetSelect = page.getByRole('combobox', { name: '甜度' }); + const options = ['全糖', '8分糖', '5分糖', '3分糖', '1分糖', '無糖']; + for (const option of options) { + await expect(sweetSelect.getByText(option)).toBeVisible(); + } + }); + + // 需求 6, 7: 訂單確認和顯示在訂購清單中 + test('確認後訂單添加到訂購清單', async ({ page }) => { + await fillOrderForm(page); + await page.getByRole('button', { name: '確認' }).click(); + const orderList = page.getByTestId('order-list'); + await expect(orderList.getByRole('row')).toHaveCount(2); // 表頭 + 1 個訂單 + await expect(orderList.getByRole('checkbox')).toBeVisible(); + }); + + // 需求 8: 刪除選定的訂單 + test('可以刪除選定的訂單', async ({ page }) => { + await fillOrderForm(page); + await page.getByRole('button', { name: '確認' }).click(); + await page.getByTestId('order-list').getByRole('checkbox').check(); + await page.getByRole('button', { name: '刪除勾選' }).click(); + await expect(page.getByTestId('order-list').getByRole('row')).toHaveCount(1); // 只剩表頭 + }); + + // 需求 9: 訂單摘要 + test('訂單摘要正確更新', async ({ page }) => { + await fillOrderForm(page); + await page.getByRole('button', { name: '確認' }).click(); + const summary = page.getByTestId('order-summary'); + await expect(summary).toContainText('總數量: 1'); + await expect(summary).toContainText('總金額: 30'); + }); + + // 需求 10: 自動填充客戶姓名 + test('第一筆訂單後自動填充客戶姓名', async ({ page }) => { + await fillOrderForm(page, '測試客戶'); + await page.getByRole('button', { name: '確認' }).click(); + await fillOrderForm(page); + const customerInput = page.getByRole('textbox', { name: '訂購人' }); + await expect(customerInput).toHaveValue('測試客戶'); + }); + + // 需求 11: 結帳流程 + test('結帳流程顯示訂單摘要並清空訂購清單', async ({ page }) => { + await fillOrderForm(page); + await page.getByRole('button', { name: '確認' }).click(); + const checkoutButton = page.getByRole('button', { name: '結帳' }); + + const dialogPromise = page.waitForEvent('dialog'); + await checkoutButton.click(); + const dialog = await dialogPromise; + + expect(dialog.message()).toContain('訂單摘要'); + expect(dialog.message()).toContain('總金額'); + + await dialog.dismiss(); + await expect(page.getByTestId('order-list').getByRole('row')).toHaveCount(1); // 只剩表頭 + }); +}); + +async function fillOrderForm(page, customerName = '測試客戶') { + await page.getByRole('combobox', { name: '品名' }).selectOption({ index: 0 }); + await page.getByRole('combobox', { name: '容量' }).selectOption({ index: 0 }); + await page.getByRole('spinbutton', { name: '數量' }).fill('1'); + await page.getByRole('combobox', { name: '溫度' }).selectOption('全冰'); + await page.getByRole('combobox', { name: '甜度' }).selectOption('全糖'); + await page.getByRole('textbox', { name: '訂購人' }).fill(customerName); +} \ No newline at end of file diff --git a/test3/tests/llm1.spec.ts b/test3/tests/llm1.spec.ts new file mode 100644 index 0000000..8ae8973 --- /dev/null +++ b/test3/tests/llm1.spec.ts @@ -0,0 +1,155 @@ +import { test, expect } from '@playwright/test'; + +test.describe('飲料訂購系統', () => { + test.beforeEach(async ({ page }) => { + await page.goto('http://localhost:8080'); // 根據需要調整 URL + }); + + // 需求 1: 使用者界面元素 + test('使用者界面元素存在且正確佈局', async ({ page }) => { + // 檢查主要元素是否存在 + await expect(page.getByRole('heading', { name: '來點什麼...' })).toBeVisible(); + await expect(page.getByTestId('price-display')).toBeVisible(); + await expect(page.getByTestId('total-display')).toBeVisible(); + await expect(page.getByRole('button', { name: '確認' })).toBeVisible(); + + // 檢查下拉式選單元素 + await expect(page.getByRole('combobox', { name: '品名' })).toBeVisible(); + await expect(page.getByRole('combobox', { name: '容量' })).toBeVisible(); + await expect(page.getByRole('combobox', { name: '溫度' })).toBeVisible(); + await expect(page.getByRole('combobox', { name: '甜度' })).toBeVisible(); + + // 檢查輸入元素 + await expect(page.getByRole('spinbutton', { name: '數量' })).toBeVisible(); + await expect(page.getByRole('textbox', { name: '訂購人' })).toBeVisible(); + }); + + // 需求 2a, 2b, 2c: 品名和容量選項 + test('品名和容量選項正確填充', async ({ page }) => { + const itemSelect = page.getByRole('combobox', { name: '品名' }); + await expect(itemSelect).toHaveCount(1); + + const itemOptions = await itemSelect.getByRole('option').all(); + expect(itemOptions.length).toBeGreaterThan(0); + expect(itemOptions.length).toBeLessThanOrEqual(10); + + // 選擇第一個品項並檢查容量選項 + await itemSelect.selectOption({ index: 0 }); + const sizeSelect = page.getByRole('combobox', { name: '容量' }); + const sizeOptions = await sizeSelect.getByRole('option').all(); + expect(sizeOptions.length).toBeGreaterThan(0); + }); + + // 需求 2d, 3: 價格和總金額計算 + test('價格和總金額計算正確', async ({ page }) => { + const itemSelect = page.getByRole('combobox', { name: '品名' }); + const sizeSelect = page.getByRole('combobox', { name: '容量' }); + const quantityInput = page.getByRole('spinbutton', { name: '數量' }); + const priceDisplay = page.getByTestId('price-display'); + const totalDisplay = page.getByTestId('total-display'); + + await itemSelect.selectOption({ index: 0 }); + await sizeSelect.selectOption({ index: 0 }); + await expect(priceDisplay).not.toHaveText('0'); + + await quantityInput.fill('2'); + const price = await priceDisplay.innerText(); + const expectedTotal = (parseInt(price) * 2).toString(); + await expect(totalDisplay).toHaveText(expectedTotal); + }); + + // 需求 4: 溫度選項 + test('溫度選項正確', async ({ page }) => { + const tempSelect = page.getByRole('combobox', { name: '溫度' }); + + // 等待選擇器元素出現並可見 + await expect(tempSelect).toBeVisible({ timeout: 5000 }); + + const expectedOptions = ['熱', '全冰', '少冰', '去冰']; + + // 獲取實際的選項 + const actualOptions = await tempSelect.getByRole('option').allInnerTexts(); + + // 檢查所有預期的選項是否都存在,忽略順序 + for (const option of expectedOptions) { + expect(actualOptions).toContain(option); + } + + // 檢查選項數量是否正確 + expect(actualOptions.length).toBe(expectedOptions.length); + + // 如果需要檢查順序,可以使用以下代碼: + // expect(actualOptions).toEqual(expectedOptions); + }); + + // 需求 5: 甜度選項 + test('甜度選項正確', async ({ page }) => { + const sweetSelect = page.getByRole('combobox', { name: '甜度' }); + const options = ['全糖', '8分糖', '5分糖', '3分糖', '1分糖', '無糖']; + for (const option of options) { + await expect(sweetSelect.getByText(option)).toBeVisible(); + } + }); + + // 需求 6, 7: 訂單確認和顯示在訂購清單中 + test('確認後訂單添加到訂購清單', async ({ page }) => { + await fillOrderForm(page); + await page.getByRole('button', { name: '確認' }).click(); + const orderList = page.getByTestId('order-list'); + await expect(orderList.getByRole('row')).toHaveCount(2); // 表頭 + 1 個訂單 + await expect(orderList.getByRole('checkbox')).toBeVisible(); + }); + + // 需求 8: 刪除選定的訂單 + test('可以刪除選定的訂單', async ({ page }) => { + await fillOrderForm(page); + await page.getByRole('button', { name: '確認' }).click(); + await page.getByTestId('order-list').getByRole('checkbox').check(); + await page.getByRole('button', { name: '刪除勾選' }).click(); + await expect(page.getByTestId('order-list').getByRole('row')).toHaveCount(1); // 只剩表頭 + }); + + // 需求 9: 訂單摘要 + test('訂單摘要正確更新', async ({ page }) => { + await fillOrderForm(page); + await page.getByRole('button', { name: '確認' }).click(); + const summary = page.getByTestId('order-summary'); + await expect(summary).toContainText('總數量: 1'); + await expect(summary).toContainText('總金額: 30'); + }); + + // 需求 10: 自動填充客戶姓名 + test('第一筆訂單後自動填充客戶姓名', async ({ page }) => { + await fillOrderForm(page, '測試客戶'); + await page.getByRole('button', { name: '確認' }).click(); + await fillOrderForm(page); + const customerInput = page.getByRole('textbox', { name: '訂購人' }); + await expect(customerInput).toHaveValue('測試客戶'); + }); + + // 需求 11: 結帳流程 + test('結帳流程顯示訂單摘要並清空訂購清單', async ({ page }) => { + await fillOrderForm(page); + await page.getByRole('button', { name: '確認' }).click(); + const checkoutButton = page.getByRole('button', { name: '結帳' }); + + const dialogPromise = page.waitForEvent('dialog'); + await checkoutButton.click(); + const dialog = await dialogPromise; + + expect(dialog.message()).toContain('訂單摘要'); + expect(dialog.message()).toContain('總金額'); + + await dialog.dismiss(); + await expect(page.getByTestId('order-list').getByRole('row')).toHaveCount(1); // 只剩表頭 + }); +}); + +async function fillOrderForm(page, customerName = '測試客戶') { + await page.getByRole('combobox', { name: '品名' }).selectOption({ index: 0 }); + await page.getByRole('combobox', { name: '容量' }).selectOption({ index: 0 }); + await page.getByRole('spinbutton', { name: '數量' }).fill('1'); + await page.getByRole('combobox', { name: '溫度' }).selectOption('全冰'); + await page.getByRole('combobox', { name: '甜度' }).selectOption('全糖'); + await page.getByRole('textbox', { name: '訂購人' }).fill(customerName); +} \ No newline at end of file diff --git a/test3/tests/llm2.spec.ts b/test3/tests/llm2.spec.ts new file mode 100644 index 0000000..f86b346 --- /dev/null +++ b/test3/tests/llm2.spec.ts @@ -0,0 +1,178 @@ +import { test, expect } from '@playwright/test'; + +test.describe('飲料訂購系統', () => { + test.beforeEach(async ({ page }) => { + await page.goto('http://localhost:8080'); // 根據需要調整 URL + }); + + // 需求 1: 使用者界面元素 + test('使用者界面元素存在且正確佈局', async ({ page }) => { + // 檢查主要元素是否存在 + await expect(page.getByRole('heading', { name: '來點什麼...' })).toBeVisible(); + await expect(page.getByTestId('price-display')).toBeVisible(); + await expect(page.getByTestId('total-display')).toBeVisible(); + await expect(page.getByRole('button', { name: '確認' })).toBeVisible(); + + // 檢查下拉式選單元素 + await expect(page.getByRole('combobox', { name: '品名' })).toBeVisible(); + await expect(page.getByRole('combobox', { name: '容量' })).toBeVisible(); + await expect(page.getByRole('combobox', { name: '溫度' })).toBeVisible(); + await expect(page.getByRole('combobox', { name: '甜度' })).toBeVisible(); + + // 檢查輸入元素 + await expect(page.getByRole('spinbutton', { name: '數量' })).toBeVisible(); + await expect(page.getByRole('textbox', { name: '訂購人' })).toBeVisible(); + }); + + // 需求 2a, 2b, 2c: 品名和容量選項 + test('品名和容量選項正確填充', async ({ page }) => { + const itemSelect = page.getByRole('combobox', { name: '品名' }); + await expect(itemSelect).toHaveCount(1); + + const itemOptions = await itemSelect.getByRole('option').all(); + expect(itemOptions.length).toBeGreaterThan(0); + expect(itemOptions.length).toBeLessThanOrEqual(10); + + // 選擇第一個品項並檢查容量選項 + await itemSelect.selectOption({ index: 0 }); + const sizeSelect = page.getByRole('combobox', { name: '容量' }); + const sizeOptions = await sizeSelect.getByRole('option').all(); + expect(sizeOptions.length).toBeGreaterThan(0); + }); + + // 需求 2d, 3: 價格和總金額計算 + test('價格和總金額計算正確', async ({ page }) => { + const itemSelect = page.getByRole('combobox', { name: '品名' }); + const sizeSelect = page.getByRole('combobox', { name: '容量' }); + const quantityInput = page.getByRole('spinbutton', { name: '數量' }); + const priceDisplay = page.getByTestId('price-display'); + const totalDisplay = page.getByTestId('total-display'); + + await itemSelect.selectOption({ index: 0 }); + await sizeSelect.selectOption({ index: 0 }); + await expect(priceDisplay).not.toHaveText('0'); + + await quantityInput.fill('2'); + const price = await priceDisplay.innerText(); + const expectedTotal = (parseInt(price) * 2).toString(); + await expect(totalDisplay).toHaveText(expectedTotal); + }); + + // 需求 4: 溫度選項 + test('溫度選項正確', async ({ page }) => { + const tempSelect = page.getByRole('combobox', { name: '溫度' }); + + // 等待選擇器元素出現並可見 + await expect(tempSelect).toBeVisible({ timeout: 5000 }); + + const expectedOptions = ['熱', '全冰', '少冰', '去冰']; + + // 獲取實際的選項 + const actualOptions = await tempSelect.getByRole('option').allInnerTexts(); + + // 檢查所有預期的選項是否都存在,忽略順序 + for (const option of expectedOptions) { + expect(actualOptions).toContain(option); + } + + // 檢查選項數量是否正確 + expect(actualOptions.length).toBe(expectedOptions.length); + + // 如果需要檢查順序,可以使用以下代碼: + // expect(actualOptions).toEqual(expectedOptions); + }); + + // 需求 5: 甜度選項 + test('甜度選項正確', async ({ page }) => { + const sweetSelect = page.getByRole('combobox', { name: '甜度' }); + + // 等待選擇器元素出現並可見 + await expect(sweetSelect).toBeVisible({ timeout: 5000 }); + + // 點擊 combobox 以打開選項列表 + await sweetSelect.click(); + + const expectedOptions = ['全糖', '8分糖', '5分糖', '3分糖', '1分糖', '無糖']; + + for (const option of expectedOptions) { + // 使用 getByRole 和 name 選項來定位每個選項 + const optionElement = sweetSelect.getByRole('option', { name: option }); + + // 等待選項可見並檢查 + await expect(optionElement).toBeVisible({ timeout: 2000 }); + + // 額外檢查:確保選項文本正確 + const optionText = await optionElement.innerText(); + expect(optionText.trim()).toBe(option); + } + + // 檢查選項數量是否正確 + const allOptions = await sweetSelect.getByRole('option').all(); + expect(allOptions.length).toBe(expectedOptions.length); + + // 關閉 combobox(可選,取決於您的 UI 行為) + await page.keyboard.press('Escape'); + }); + + // 需求 6, 7: 訂單確認和顯示在訂購清單中 + test('確認後訂單添加到訂購清單', async ({ page }) => { + await fillOrderForm(page); + await page.getByRole('button', { name: '確認' }).click(); + const orderList = page.getByTestId('order-list'); + await expect(orderList.getByRole('row')).toHaveCount(2); // 表頭 + 1 個訂單 + await expect(orderList.getByRole('checkbox')).toBeVisible(); + }); + + // 需求 8: 刪除選定的訂單 + test('可以刪除選定的訂單', async ({ page }) => { + await fillOrderForm(page); + await page.getByRole('button', { name: '確認' }).click(); + await page.getByTestId('order-list').getByRole('checkbox').check(); + await page.getByRole('button', { name: '刪除勾選' }).click(); + await expect(page.getByTestId('order-list').getByRole('row')).toHaveCount(1); // 只剩表頭 + }); + + // 需求 9: 訂單摘要 + test('訂單摘要正確更新', async ({ page }) => { + await fillOrderForm(page); + await page.getByRole('button', { name: '確認' }).click(); + const summary = page.getByTestId('order-summary'); + await expect(summary).toContainText('總數量: 1'); + await expect(summary).toContainText('總金額: 30'); + }); + + // 需求 10: 自動填充客戶姓名 + test('第一筆訂單後自動填充客戶姓名', async ({ page }) => { + await fillOrderForm(page, '測試客戶'); + await page.getByRole('button', { name: '確認' }).click(); + await fillOrderForm(page); + const customerInput = page.getByRole('textbox', { name: '訂購人' }); + await expect(customerInput).toHaveValue('測試客戶'); + }); + + // 需求 11: 結帳流程 + test('結帳流程顯示訂單摘要並清空訂購清單', async ({ page }) => { + await fillOrderForm(page); + await page.getByRole('button', { name: '確認' }).click(); + const checkoutButton = page.getByRole('button', { name: '結帳' }); + + const dialogPromise = page.waitForEvent('dialog'); + await checkoutButton.click(); + const dialog = await dialogPromise; + + expect(dialog.message()).toContain('訂單摘要'); + expect(dialog.message()).toContain('總金額'); + + await dialog.dismiss(); + await expect(page.getByTestId('order-list').getByRole('row')).toHaveCount(1); // 只剩表頭 + }); +}); + +async function fillOrderForm(page, customerName = '測試客戶') { + await page.getByRole('combobox', { name: '品名' }).selectOption({ index: 0 }); + await page.getByRole('combobox', { name: '容量' }).selectOption({ index: 0 }); + await page.getByRole('spinbutton', { name: '數量' }).fill('1'); + await page.getByRole('combobox', { name: '溫度' }).selectOption('全冰'); + await page.getByRole('combobox', { name: '甜度' }).selectOption('全糖'); + await page.getByRole('textbox', { name: '訂購人' }).fill(customerName); +} \ No newline at end of file diff --git a/test3/tests/llm3.spec.ts b/test3/tests/llm3.spec.ts new file mode 100644 index 0000000..8c60a88 --- /dev/null +++ b/test3/tests/llm3.spec.ts @@ -0,0 +1,185 @@ +import { test, expect } from '@playwright/test'; + +test.describe('飲料訂購系統', () => { + test.beforeEach(async ({ page }) => { + await page.goto('http://localhost:8080'); // 根據需要調整 URL + }); + + // 需求 1: 使用者界面元素 + test('使用者界面元素存在且正確佈局', async ({ page }) => { + // 檢查主要元素是否存在 + await expect(page.getByRole('heading', { name: '來點什麼...' })).toBeVisible(); + await expect(page.getByTestId('price-display')).toBeVisible(); + await expect(page.getByTestId('total-display')).toBeVisible(); + await expect(page.getByRole('button', { name: '確認' })).toBeVisible(); + + // 檢查下拉式選單元素 + await expect(page.getByRole('combobox', { name: '品名' })).toBeVisible(); + await expect(page.getByRole('combobox', { name: '容量' })).toBeVisible(); + await expect(page.getByRole('combobox', { name: '溫度' })).toBeVisible(); + await expect(page.getByRole('combobox', { name: '甜度' })).toBeVisible(); + + // 檢查輸入元素 + await expect(page.getByRole('spinbutton', { name: '數量' })).toBeVisible(); + await expect(page.getByRole('textbox', { name: '訂購人' })).toBeVisible(); + }); + + // 需求 2a, 2b, 2c: 品名和容量選項 + test('品名和容量選項正確填充', async ({ page }) => { + const itemSelect = page.getByRole('combobox', { name: '品名' }); + await expect(itemSelect).toHaveCount(1); + + const itemOptions = await itemSelect.getByRole('option').all(); + expect(itemOptions.length).toBeGreaterThan(0); + expect(itemOptions.length).toBeLessThanOrEqual(10); + + // 選擇第一個品項並檢查容量選項 + await itemSelect.selectOption({ index: 0 }); + const sizeSelect = page.getByRole('combobox', { name: '容量' }); + const sizeOptions = await sizeSelect.getByRole('option').all(); + expect(sizeOptions.length).toBeGreaterThan(0); + }); + + // 需求 2d, 3: 價格和總金額計算 + test('價格和總金額計算正確', async ({ page }) => { + const itemSelect = page.getByRole('combobox', { name: '品名' }); + const sizeSelect = page.getByRole('combobox', { name: '容量' }); + const quantityInput = page.getByRole('spinbutton', { name: '數量' }); + const priceDisplay = page.getByTestId('price-display'); + const totalDisplay = page.getByTestId('total-display'); + + await itemSelect.selectOption({ index: 0 }); + await sizeSelect.selectOption({ index: 0 }); + await expect(priceDisplay).not.toHaveText('0'); + + await quantityInput.fill('2'); + const price = await priceDisplay.innerText(); + const expectedTotal = (parseInt(price) * 2).toString(); + await expect(totalDisplay).toHaveText(expectedTotal); + }); + + // 需求 4: 溫度選項 + test('溫度選項正確', async ({ page }) => { + const tempSelect = page.getByRole('combobox', { name: '溫度' }); + + // 等待選擇器元素出現並可見 + await expect(tempSelect).toBeVisible({ timeout: 5000 }); + + const expectedOptions = ['熱', '全冰', '少冰', '去冰']; + + // 獲取實際的選項 + const actualOptions = await tempSelect.getByRole('option').allInnerTexts(); + + // 檢查所有預期的選項是否都存在,忽略順序 + for (const option of expectedOptions) { + expect(actualOptions).toContain(option); + } + + // 檢查選項數量是否正確 + expect(actualOptions.length).toBe(expectedOptions.length); + + // 如果需要檢查順序,可以使用以下代碼: + // expect(actualOptions).toEqual(expectedOptions); + }); + + // 需求 5: 甜度選項 + test('甜度選項正確', async ({ page }) => { + const sweetSelect = page.getByRole('combobox', { name: '甜度' }); + + // 等待選擇器元素出現並可交互 + await expect(sweetSelect).toBeEnabled({ timeout: 5000 }); + + // 點擊 combobox 以打開選項列表 + await sweetSelect.click(); + + const expectedOptions = ['全糖', '8分糖', '5分糖', '3分糖', '1分糖', '無糖']; + + for (const option of expectedOptions) { + // 使用 getByRole 和 name 選項來定位每個選項 + const optionElement = sweetSelect.getByRole('option', { name: option }); + + // 等待選項存在於 DOM 中 + await expect(optionElement).toBeAttached({ timeout: 2000 }); + + // 檢查選項是否可以被選擇 + await expect(optionElement).toBeEnabled(); + + // 額外檢查:確保選項文本正確 + const optionText = await optionElement.innerText(); + expect(optionText.trim()).toBe(option); + } + + // 檢查選項數量是否正確 + const allOptions = await sweetSelect.getByRole('option').all(); + expect(allOptions.length).toBe(expectedOptions.length); + + // 選擇一個選項來驗證功能 + await sweetSelect.selectOption(expectedOptions[0]); + await expect(sweetSelect).toHaveValue(expectedOptions[0]); + + // 關閉 combobox(可選,取決於您的 UI 行為) + await page.keyboard.press('Escape'); + }); + + // 需求 6, 7: 訂單確認和顯示在訂購清單中 + test('確認後訂單添加到訂購清單', async ({ page }) => { + await fillOrderForm(page); + await page.getByRole('button', { name: '確認' }).click(); + const orderList = page.getByTestId('order-list'); + await expect(orderList.getByRole('row')).toHaveCount(2); // 表頭 + 1 個訂單 + await expect(orderList.getByRole('checkbox')).toBeVisible(); + }); + + // 需求 8: 刪除選定的訂單 + test('可以刪除選定的訂單', async ({ page }) => { + await fillOrderForm(page); + await page.getByRole('button', { name: '確認' }).click(); + await page.getByTestId('order-list').getByRole('checkbox').check(); + await page.getByRole('button', { name: '刪除勾選' }).click(); + await expect(page.getByTestId('order-list').getByRole('row')).toHaveCount(1); // 只剩表頭 + }); + + // 需求 9: 訂單摘要 + test('訂單摘要正確更新', async ({ page }) => { + await fillOrderForm(page); + await page.getByRole('button', { name: '確認' }).click(); + const summary = page.getByTestId('order-summary'); + await expect(summary).toContainText('總數量: 1'); + await expect(summary).toContainText('總金額: 30'); + }); + + // 需求 10: 自動填充客戶姓名 + test('第一筆訂單後自動填充客戶姓名', async ({ page }) => { + await fillOrderForm(page, '測試客戶'); + await page.getByRole('button', { name: '確認' }).click(); + await fillOrderForm(page); + const customerInput = page.getByRole('textbox', { name: '訂購人' }); + await expect(customerInput).toHaveValue('測試客戶'); + }); + + // 需求 11: 結帳流程 + test('結帳流程顯示訂單摘要並清空訂購清單', async ({ page }) => { + await fillOrderForm(page); + await page.getByRole('button', { name: '確認' }).click(); + const checkoutButton = page.getByRole('button', { name: '結帳' }); + + const dialogPromise = page.waitForEvent('dialog'); + await checkoutButton.click(); + const dialog = await dialogPromise; + + expect(dialog.message()).toContain('訂單摘要'); + expect(dialog.message()).toContain('總金額'); + + await dialog.dismiss(); + await expect(page.getByTestId('order-list').getByRole('row')).toHaveCount(1); // 只剩表頭 + }); +}); + +async function fillOrderForm(page, customerName = '測試客戶') { + await page.getByRole('combobox', { name: '品名' }).selectOption({ index: 0 }); + await page.getByRole('combobox', { name: '容量' }).selectOption({ index: 0 }); + await page.getByRole('spinbutton', { name: '數量' }).fill('1'); + await page.getByRole('combobox', { name: '溫度' }).selectOption('全冰'); + await page.getByRole('combobox', { name: '甜度' }).selectOption('全糖'); + await page.getByRole('textbox', { name: '訂購人' }).fill(customerName); +} \ No newline at end of file diff --git a/test3/tests/llm4.spec.ts b/test3/tests/llm4.spec.ts new file mode 100644 index 0000000..fd8bd7e --- /dev/null +++ b/test3/tests/llm4.spec.ts @@ -0,0 +1,205 @@ +import { test, expect } from '@playwright/test'; + +test.describe('飲料訂購系統', () => { + test.beforeEach(async ({ page }) => { + await page.goto('http://localhost:8080'); // 根據需要調整 URL + }); + + // 需求 1: 使用者界面元素 + test('使用者界面元素存在且正確佈局', async ({ page }) => { + // 檢查主要元素是否存在 + await expect(page.getByRole('heading', { name: '來點什麼...' })).toBeVisible(); + await expect(page.getByTestId('price-display')).toBeVisible(); + await expect(page.getByTestId('total-display')).toBeVisible(); + await expect(page.getByRole('button', { name: '確認' })).toBeVisible(); + + // 檢查下拉式選單元素 + await expect(page.getByRole('combobox', { name: '品名' })).toBeVisible(); + await expect(page.getByRole('combobox', { name: '容量' })).toBeVisible(); + await expect(page.getByRole('combobox', { name: '溫度' })).toBeVisible(); + await expect(page.getByRole('combobox', { name: '甜度' })).toBeVisible(); + + // 檢查輸入元素 + await expect(page.getByRole('spinbutton', { name: '數量' })).toBeVisible(); + await expect(page.getByRole('textbox', { name: '訂購人' })).toBeVisible(); + }); + + // 需求 2a, 2b, 2c: 品名和容量選項 + test('品名和容量選項正確填充', async ({ page }) => { + const itemSelect = page.getByRole('combobox', { name: '品名' }); + await expect(itemSelect).toHaveCount(1); + + const itemOptions = await itemSelect.getByRole('option').all(); + expect(itemOptions.length).toBeGreaterThan(0); + expect(itemOptions.length).toBeLessThanOrEqual(10); + + // 選擇第一個品項並檢查容量選項 + await itemSelect.selectOption({ index: 0 }); + const sizeSelect = page.getByRole('combobox', { name: '容量' }); + const sizeOptions = await sizeSelect.getByRole('option').all(); + expect(sizeOptions.length).toBeGreaterThan(0); + }); + + // 需求 2d, 3: 價格和總金額計算 + test('價格和總金額計算正確', async ({ page }) => { + const itemSelect = page.getByRole('combobox', { name: '品名' }); + const sizeSelect = page.getByRole('combobox', { name: '容量' }); + const quantityInput = page.getByRole('spinbutton', { name: '數量' }); + const priceDisplay = page.getByTestId('price-display'); + const totalDisplay = page.getByTestId('total-display'); + + await itemSelect.selectOption({ index: 0 }); + await sizeSelect.selectOption({ index: 0 }); + await expect(priceDisplay).not.toHaveText('0'); + + await quantityInput.fill('2'); + const price = await priceDisplay.innerText(); + const expectedTotal = (parseInt(price) * 2).toString(); + await expect(totalDisplay).toHaveText(expectedTotal); + }); + + // 需求 4: 溫度選項 + test('溫度選項正確', async ({ page }) => { + const tempSelect = page.getByRole('combobox', { name: '溫度' }); + + // 等待選擇器元素出現並可見 + await expect(tempSelect).toBeVisible({ timeout: 5000 }); + + const expectedOptions = ['熱', '全冰', '少冰', '去冰']; + + // 獲取實際的選項 + const actualOptions = await tempSelect.getByRole('option').allInnerTexts(); + + // 檢查所有預期的選項是否都存在,忽略順序 + for (const option of expectedOptions) { + expect(actualOptions).toContain(option); + } + + // 檢查選項數量是否正確 + expect(actualOptions.length).toBe(expectedOptions.length); + + // 如果需要檢查順序,可以使用以下代碼: + // expect(actualOptions).toEqual(expectedOptions); + }); + + // 需求 5: 甜度選項 + test('甜度選項正確', async ({ page }) => { + const sweetSelect = page.getByRole('combobox', { name: '甜度' }); + + // 等待選擇器元素出現並可交互 + await expect(sweetSelect).toBeEnabled({ timeout: 5000 }); + + // 點擊 combobox 以打開選項列表 + await sweetSelect.click(); + + const expectedOptions = ['全糖', '8分糖', '5分糖', '3分糖', '1分糖', '無糖']; + + for (const option of expectedOptions) { + // 使用 getByRole 和 name 選項來定位每個選項 + const optionElement = sweetSelect.getByRole('option', { name: option }); + + // 等待選項存在於 DOM 中 + await expect(optionElement).toBeAttached({ timeout: 2000 }); + + // 檢查選項是否可以被選擇 + await expect(optionElement).toBeEnabled(); + + // 額外檢查:確保選項文本正確 + const optionText = await optionElement.innerText(); + expect(optionText.trim()).toBe(option); + } + + // 檢查選項數量是否正確 + const allOptions = await sweetSelect.getByRole('option').all(); + expect(allOptions.length).toBe(expectedOptions.length); + + // 選擇一個選項來驗證功能 + await sweetSelect.selectOption(expectedOptions[0]); + await expect(sweetSelect).toHaveValue(expectedOptions[0]); + + // 關閉 combobox(可選,取決於您的 UI 行為) + await page.keyboard.press('Escape'); + }); + + // 需求 6, 7: 訂單確認和顯示在訂購清單中 + test('確認後訂單添加到訂購清單', async ({ page }) => { + await fillOrderForm(page); + await page.getByRole('button', { name: '確認' }).click(); + const orderList = page.getByTestId('order-list'); + await expect(orderList.getByRole('row')).toHaveCount(2); // 表頭 + 1 個訂單 + await expect(orderList.getByRole('checkbox')).toBeVisible(); + }); + + // 需求 8: 刪除選定的訂單 + test('可以刪除選定的訂單', async ({ page }) => { + await fillOrderForm(page); + await page.getByRole('button', { name: '確認' }).click(); + await page.getByTestId('order-list').getByRole('checkbox').check(); + await page.getByRole('button', { name: '刪除勾選' }).click(); + await expect(page.getByTestId('order-list').getByRole('row')).toHaveCount(1); // 只剩表頭 + }); + + // 需求 9: 訂單摘要 + test('訂單摘要正確更新', async ({ page }) => { + await fillOrderForm(page); + await page.getByRole('button', { name: '確認' }).click(); + const summary = page.getByTestId('order-summary'); + await expect(summary).toContainText('總數量: 1'); + await expect(summary).toContainText('總金額: 30'); + }); + + // 需求 10: 自動填充客戶姓名 + test('第一筆訂單後自動填充客戶姓名', async ({ page }) => { + await fillOrderForm(page, '測試客戶'); + await page.getByRole('button', { name: '確認' }).click(); + await fillOrderForm(page); + const customerInput = page.getByRole('textbox', { name: '訂購人' }); + await expect(customerInput).toHaveValue('測試客戶'); + }); + + // 需求 11: 結帳流程 + test('結帳流程顯示訂單摘要並清空訂購清單', async ({ page }) => { + // 添加訂單 + await fillOrderForm(page); + await page.getByRole('button', { name: '確認' }).click(); + + // 確保訂單已經添加到清單中 + await expect(page.getByTestId('order-list').getByRole('row')).toHaveCount(2); // 表頭 + 1 個訂單 + + const checkoutButton = page.getByRole('button', { name: '結帳' }); + + // 等待結帳按鈕可用 + await expect(checkoutButton).toBeEnabled(); + + // 設置對話框處理 + page.on('dialog', async dialog => { + console.log('對話框信息:', dialog.message()); + expect(dialog.message()).toContain('訂單摘要'); + expect(dialog.message()).toContain('總金額'); + await dialog.accept(); + }); + + // 點擊結帳按鈕 + await checkoutButton.click(); + + // 等待一段時間,確保對話框已經處理完畢 + await page.waitForTimeout(1000); + + // 檢查訂購清單是否被清空 + await expect(page.getByTestId('order-list').getByRole('row')).toHaveCount(1, { timeout: 5000 }); // 只剩表頭 + + // 檢查訂單摘要是否被重置 + const summary = page.getByTestId('order-summary'); + await expect(summary).toContainText('總數量: 0'); + await expect(summary).toContainText('總金額: 0'); + }); +}); + +async function fillOrderForm(page, customerName = '測試客戶') { + await page.getByRole('combobox', { name: '品名' }).selectOption({ index: 0 }); + await page.getByRole('combobox', { name: '容量' }).selectOption({ index: 0 }); + await page.getByRole('spinbutton', { name: '數量' }).fill('1'); + await page.getByRole('combobox', { name: '溫度' }).selectOption('全冰'); + await page.getByRole('combobox', { name: '甜度' }).selectOption('全糖'); + await page.getByRole('textbox', { name: '訂購人' }).fill(customerName); +} \ No newline at end of file