From 9254c0183ec732d3aeb4ac2fd11e3ac1b3c35738 Mon Sep 17 00:00:00 2001 From: Linpiing Date: Wed, 18 Sep 2024 17:52:25 +0700 Subject: [PATCH] test : Create Script Role&Permission --- reports.json | 167 ++ .../JWS_RP_001_CorporateCustomer.spec.ts | 181 ++ .../JWS_RP_002_HeadOfAdmin.spec.ts | 185 ++ .../JWS_RP_003_Sale.spec.ts | 184 ++ .../JWS_RP_004_DocumentChecker.spec.ts | 178 ++ .../JWS_RP_005_SaleAgent.spec.ts | 178 ++ .../JWS_RP_006_Messenger.spec.ts | 178 ++ .../JWS_RP_007_Account.spec.ts | 176 ++ .../JWS_RP_008_Admin.spec.ts | 180 ++ .../JWS_RP_009_Executive.spec.ts | 179 ++ .../JWS_RP_010_DataEntry.spec.ts | 176 ++ .../JWS_RP_011_HeadOfAccount.spec.ts | 178 ++ .../JWS_RP_012_HeadOfSale.spec.ts | 179 ++ .../JWS_RP_013_PersonalCustomer.spec.ts | 179 ++ .../JWS_RP_014_BranchManager.spec.ts | 178 ++ .../JWS_BM_001_CreateHeadquarters.spec.ts | 179 +- .../JWS_BM_002_CreateHeadquarterFail.spec.ts | 187 +- .../JWS_BM_003_CreateSub-branch.spec.ts | 97 +- .../JWS_BM_004_CreateSub-branchFail.spec.ts | 169 +- .../JWS_BM_005_CreateServicePoint.spec.ts | 118 + .../JWS_BM_005_SelectTypeBranch.spec.ts | 91 - .../JWS_BM_006_CreateServicePointFail.spec.ts | 112 + .../JWS_BM_007_EditBranch.spec.ts | 37 - .../JWS_BM_007_SelectTypeBranch.spec.ts | 387 +++ ...JWS_BM_008_CloseStatusBranchandSub.spec.ts | 58 - .../JWS_BM_008_ViewDetail.spec.ts | 91 + .../JWS_BM_009_EditBranch.spec.ts | 129 + .../JWS_BM_010_StatusBranchandSubType.spec.ts | 229 ++ .../JWS_BM_011_SearchBranchmanagement.spec.ts | 85 + .../JWS_BM_012_CloseStatusBranch.spec.ts | 99 + .../JWS_BM_013_DeleteBranch.spec.ts | 217 ++ .../JWS_PM_001_CreatePersonnel.spec.ts | 1035 +++++--- .../JWS_PM_002_CreatePersonnelFail.spec.ts | 128 + .../JWS_PM_003_ViewDetail.spec.ts | 109 + .../JWS_PM_004_EditPersonnel.spec.ts | 243 ++ .../JWS_PM_005_StatusPersonnel.spec.ts | 98 + ...6_SearchPersonnel(ยังไม่เสร็จทำทีหลัง).spec.ts} | 0 .../JWS_PM_007_StatusPersonnelType.spec.ts | 355 +++ .../JWS_PM_008_TypePersonnelFields.spec.ts | 2084 +++++++++++++++++ .../JWS_MC_001_CreateNaturalperoson.spec.ts | 118 + ...WS_MC_002_CreateNaturalperosonfail.spec.ts | 249 ++ .../JWS_MC_003_DetailNaturalperson.spec.ts} | 11 +- .../JWS_MC_004_EditNaturalperson.spec.ts | 41 + .../JWS_MC_005_DeleteNaturalperson.spec.ts | 34 + .../JWS_MC_006_StatusNaturalperson.spec.ts | 38 + .../JWS_MC_007_CreateLegalentitly.spec.ts | 132 ++ .../JWS_MC_008_CreateLegalentitlyfail.spec.ts | 1226 ++++++++++ .../JWS_MC_009_DetailLegalentitly.spec.ts} | 9 +- .../JWS_MC_010_EditLegalentitly.spec.ts | 37 + .../JWS_MC_011_DeleteLegalentitly.spec.ts | 35 + .../JWS_MC_012_StatusLegalentitly.spec.ts | 39 + .../JWS_MC_013_DropdownEmployertype.spec.ts} | 40 +- .../JWS_MC_014_SearchManageCustomer.spec.ts | 43 + ...MC_015_FilterManageStatusCustomer.spec.ts} | 20 +- .../JWS_MC_016_CreateEmployee.spec.ts | 98 + .../JWS_MC_017_CreateEmployeeFail.spec.ts | 297 +++ .../JWS_MC_018_SeachEmployee.spec.ts | 44 + .../JWS_MC_019_FliterStatusEmployee.spec.ts | 45 + .../JWS_MC_020_DetailEmployee.spec.ts | 33 + .../JWS_MC_021_EditEmployee.spec.ts | 33 + .../JWS_MC_022_DeleteEmployee.spec.ts | 33 + .../JWS_MC_023_StatusEmployee.spec.ts} | 17 +- .../JWS_MC_024_DropdownEmployeetype.spec.ts | 72 + ...C_025_CreateSubBranchNaturalperson.spec.ts | 71 + ...C_026_CreateSubBranchLegalentitly.spec.ts} | 10 +- ...D_001_CreateProductandServiceGroup.spec.ts | 115 + tests/Datafile/Pic1.jpg | Bin 0 -> 150709 bytes 67 files changed, 11224 insertions(+), 729 deletions(-) create mode 100644 reports.json create mode 100644 tests/00-Role&Permission/JWS_RP_001_CorporateCustomer.spec.ts create mode 100644 tests/00-Role&Permission/JWS_RP_002_HeadOfAdmin.spec.ts create mode 100644 tests/00-Role&Permission/JWS_RP_003_Sale.spec.ts create mode 100644 tests/00-Role&Permission/JWS_RP_004_DocumentChecker.spec.ts create mode 100644 tests/00-Role&Permission/JWS_RP_005_SaleAgent.spec.ts create mode 100644 tests/00-Role&Permission/JWS_RP_006_Messenger.spec.ts create mode 100644 tests/00-Role&Permission/JWS_RP_007_Account.spec.ts create mode 100644 tests/00-Role&Permission/JWS_RP_008_Admin.spec.ts create mode 100644 tests/00-Role&Permission/JWS_RP_009_Executive.spec.ts create mode 100644 tests/00-Role&Permission/JWS_RP_010_DataEntry.spec.ts create mode 100644 tests/00-Role&Permission/JWS_RP_011_HeadOfAccount.spec.ts create mode 100644 tests/00-Role&Permission/JWS_RP_012_HeadOfSale.spec.ts create mode 100644 tests/00-Role&Permission/JWS_RP_013_PersonalCustomer.spec.ts create mode 100644 tests/00-Role&Permission/JWS_RP_014_BranchManager.spec.ts create mode 100644 tests/01-Admin-BranchManagement/JWS_BM_005_CreateServicePoint.spec.ts delete mode 100644 tests/01-Admin-BranchManagement/JWS_BM_005_SelectTypeBranch.spec.ts create mode 100644 tests/01-Admin-BranchManagement/JWS_BM_006_CreateServicePointFail.spec.ts delete mode 100644 tests/01-Admin-BranchManagement/JWS_BM_007_EditBranch.spec.ts create mode 100644 tests/01-Admin-BranchManagement/JWS_BM_007_SelectTypeBranch.spec.ts delete mode 100644 tests/01-Admin-BranchManagement/JWS_BM_008_CloseStatusBranchandSub.spec.ts create mode 100644 tests/01-Admin-BranchManagement/JWS_BM_008_ViewDetail.spec.ts create mode 100644 tests/01-Admin-BranchManagement/JWS_BM_009_EditBranch.spec.ts create mode 100644 tests/01-Admin-BranchManagement/JWS_BM_010_StatusBranchandSubType.spec.ts create mode 100644 tests/01-Admin-BranchManagement/JWS_BM_011_SearchBranchmanagement.spec.ts create mode 100644 tests/01-Admin-BranchManagement/JWS_BM_012_CloseStatusBranch.spec.ts create mode 100644 tests/01-Admin-BranchManagement/JWS_BM_013_DeleteBranch.spec.ts create mode 100644 tests/02-Admin-PersonnelManagement/JWS_PM_002_CreatePersonnelFail.spec.ts create mode 100644 tests/02-Admin-PersonnelManagement/JWS_PM_003_ViewDetail.spec.ts create mode 100644 tests/02-Admin-PersonnelManagement/JWS_PM_004_EditPersonnel.spec.ts create mode 100644 tests/02-Admin-PersonnelManagement/JWS_PM_005_StatusPersonnel.spec.ts rename tests/02-Admin-PersonnelManagement/{JWS_PM_005_SearchPersonnel.spec.ts => JWS_PM_006_SearchPersonnel(ยังไม่เสร็จทำทีหลัง).spec.ts} (100%) create mode 100644 tests/02-Admin-PersonnelManagement/JWS_PM_007_StatusPersonnelType.spec.ts create mode 100644 tests/02-Admin-PersonnelManagement/JWS_PM_008_TypePersonnelFields.spec.ts create mode 100644 tests/03-Admin-ManageCustomer/JWS_MC_001_CreateNaturalperoson.spec.ts create mode 100644 tests/03-Admin-ManageCustomer/JWS_MC_002_CreateNaturalperosonfail.spec.ts rename tests/{02-Admin-PersonnelManagement/JWS_PM_002_ViewDetail.spec.ts => 03-Admin-ManageCustomer/JWS_MC_003_DetailNaturalperson.spec.ts} (68%) create mode 100644 tests/03-Admin-ManageCustomer/JWS_MC_004_EditNaturalperson.spec.ts create mode 100644 tests/03-Admin-ManageCustomer/JWS_MC_005_DeleteNaturalperson.spec.ts create mode 100644 tests/03-Admin-ManageCustomer/JWS_MC_006_StatusNaturalperson.spec.ts create mode 100644 tests/03-Admin-ManageCustomer/JWS_MC_007_CreateLegalentitly.spec.ts create mode 100644 tests/03-Admin-ManageCustomer/JWS_MC_008_CreateLegalentitlyfail.spec.ts rename tests/{02-Admin-PersonnelManagement/JWS_PM_003_EditPersonnel.spec.ts => 03-Admin-ManageCustomer/JWS_MC_009_DetailLegalentitly.spec.ts} (73%) create mode 100644 tests/03-Admin-ManageCustomer/JWS_MC_010_EditLegalentitly.spec.ts create mode 100644 tests/03-Admin-ManageCustomer/JWS_MC_011_DeleteLegalentitly.spec.ts create mode 100644 tests/03-Admin-ManageCustomer/JWS_MC_012_StatusLegalentitly.spec.ts rename tests/{01-Admin-BranchManagement/JWS_BM_009_SearchBranchmanagement.spec.ts => 03-Admin-ManageCustomer/JWS_MC_013_DropdownEmployertype.spec.ts} (56%) create mode 100644 tests/03-Admin-ManageCustomer/JWS_MC_014_SearchManageCustomer.spec.ts rename tests/{02-Admin-PersonnelManagement/JWS_PM_006_FilterStatusPersonnel.spec.ts => 03-Admin-ManageCustomer/JWS_MC_015_FilterManageStatusCustomer.spec.ts} (61%) create mode 100644 tests/03-Admin-ManageCustomer/JWS_MC_016_CreateEmployee.spec.ts create mode 100644 tests/03-Admin-ManageCustomer/JWS_MC_017_CreateEmployeeFail.spec.ts create mode 100644 tests/03-Admin-ManageCustomer/JWS_MC_018_SeachEmployee.spec.ts create mode 100644 tests/03-Admin-ManageCustomer/JWS_MC_019_FliterStatusEmployee.spec.ts create mode 100644 tests/03-Admin-ManageCustomer/JWS_MC_020_DetailEmployee.spec.ts create mode 100644 tests/03-Admin-ManageCustomer/JWS_MC_021_EditEmployee.spec.ts create mode 100644 tests/03-Admin-ManageCustomer/JWS_MC_022_DeleteEmployee.spec.ts rename tests/{02-Admin-PersonnelManagement/JWS_PM_004_StatusPersonnel.spec.ts => 03-Admin-ManageCustomer/JWS_MC_023_StatusEmployee.spec.ts} (63%) create mode 100644 tests/03-Admin-ManageCustomer/JWS_MC_024_DropdownEmployeetype.spec.ts create mode 100644 tests/03-Admin-ManageCustomer/JWS_MC_025_CreateSubBranchNaturalperson.spec.ts rename tests/{01-Admin-BranchManagement/JWS_BM_006_ViewDetail.spec.ts => 03-Admin-ManageCustomer/JWS_MC_026_CreateSubBranchLegalentitly.spec.ts} (70%) create mode 100644 tests/04-ProductandService/JWS_PD_001_CreateProductandServiceGroup.spec.ts create mode 100644 tests/Datafile/Pic1.jpg diff --git a/reports.json b/reports.json new file mode 100644 index 00000000..697c1be6 --- /dev/null +++ b/reports.json @@ -0,0 +1,167 @@ +{ + "config": { + "configFile": "/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/playwright.config.ts", + "rootDir": "/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests", + "forbidOnly": false, + "fullyParallel": true, + "globalSetup": null, + "globalTeardown": null, + "globalTimeout": 0, + "grep": {}, + "grepInvert": null, + "maxFailures": 0, + "metadata": { + "actualWorkers": 1 + }, + "preserveOutput": "always", + "reporter": [ + [ + "json", + { + "outputFile": "reports.json" + } + ] + ], + "reportSlowTests": { + "max": 5, + "threshold": 15000 + }, + "quiet": false, + "projects": [ + { + "outputDir": "/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/test-results", + "repeatEach": 1, + "retries": 0, + "metadata": {}, + "id": "chromium", + "name": "chromium", + "testDir": "/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests", + "testIgnore": [], + "testMatch": [ + "**/*.@(spec|test).?(c|m)[jt]s?(x)" + ], + "timeout": 30000 + } + ], + "shard": null, + "updateSnapshots": "missing", + "version": "1.44.1", + "workers": 1, + "webServer": null + }, + "suites": [ + { + "title": "01-Admin-BranchManagement/JWS_BM_001_CreateHeadquarters.spec.ts", + "file": "01-Admin-BranchManagement/JWS_BM_001_CreateHeadquarters.spec.ts", + "column": 0, + "line": 0, + "specs": [ + { + "title": "Login", + "ok": true, + "tags": [], + "tests": [ + { + "timeout": 30000, + "annotations": [], + "expectedStatus": "passed", + "projectId": "chromium", + "projectName": "chromium", + "results": [ + { + "workerIndex": 4, + "status": "passed", + "duration": 3024, + "errors": [], + "stdout": [], + "stderr": [], + "retry": 0, + "startTime": "2024-07-30T02:59:00.817Z", + "attachments": [] + } + ], + "status": "expected" + } + ], + "id": "8c5091bd59605f227965-8109f0f4a59e27330a76", + "file": "01-Admin-BranchManagement/JWS_BM_001_CreateHeadquarters.spec.ts", + "line": 16, + "column": 1 + }, + { + "title": "Create Branch Managenment", + "ok": true, + "tags": [], + "tests": [ + { + "timeout": 30000, + "annotations": [], + "expectedStatus": "passed", + "projectId": "chromium", + "projectName": "chromium", + "results": [ + { + "workerIndex": 4, + "status": "passed", + "duration": 5091, + "errors": [], + "stdout": [], + "stderr": [], + "retry": 0, + "startTime": "2024-07-30T02:59:05.659Z", + "attachments": [] + } + ], + "status": "expected" + } + ], + "id": "8c5091bd59605f227965-5a0d70f27623401a3479", + "file": "01-Admin-BranchManagement/JWS_BM_001_CreateHeadquarters.spec.ts", + "line": 27, + "column": 1 + }, + { + "title": "Create Branch Managenment Second", + "ok": true, + "tags": [], + "tests": [ + { + "timeout": 30000, + "annotations": [], + "expectedStatus": "passed", + "projectId": "chromium", + "projectName": "chromium", + "results": [ + { + "workerIndex": 4, + "status": "passed", + "duration": 5029, + "errors": [], + "stdout": [], + "stderr": [], + "retry": 0, + "startTime": "2024-07-30T02:59:10.755Z", + "attachments": [] + } + ], + "status": "expected" + } + ], + "id": "8c5091bd59605f227965-d619bd2184e7f07d4970", + "file": "01-Admin-BranchManagement/JWS_BM_001_CreateHeadquarters.spec.ts", + "line": 52, + "column": 1 + } + ] + } + ], + "errors": [], + "stats": { + "startTime": "2024-07-30T02:59:00.334Z", + "duration": 15556.794999999925, + "expected": 3, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + } +} \ No newline at end of file diff --git a/tests/00-Role&Permission/JWS_RP_001_CorporateCustomer.spec.ts b/tests/00-Role&Permission/JWS_RP_001_CorporateCustomer.spec.ts new file mode 100644 index 00000000..9e736e43 --- /dev/null +++ b/tests/00-Role&Permission/JWS_RP_001_CorporateCustomer.spec.ts @@ -0,0 +1,181 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; +import { Console, error, log } from 'console'; +import { waitForDebugger } from 'inspector'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Create Personnel - ตำแหน่ง Corporate Customer', async () => { + await page.click('id=menu-icon-personnel-management'); + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + + // กรอกข้อมูลพื้นฐานของบุคคลากร + await page.click("//i[@aria-hidden='false']"); + await page.waitForSelector('id=select-hq-id', { + state: 'visible', + }); + await page.click('id=select-hq-id'); + await page.click("//span[normalize-space(text())='CMO00000']"); + await page.waitForSelector('id=select-br-id', { state: 'visible' }); + await page.click('id=select-br-id'); + await page.click('id=select-br-id_4'); + await page.fill('id=input-username', 'corporatecus'); + await page.click('id=select-user-type'); + await page.click('id=select-user-type_0'); + await page.click('id=select-user-role'); + await page.click('id=select-user-role_0'); + // await page.click("//div[@role='option']"); + + // กรอกชื่อข้อมูลพื้นฐาน + await page.fill('id=input-citizen-id', '1282262422820'); + await page.click("//label[@for='form-dialog-personnel-select-prefix-name']"); + await page.click('id=form-dialog-personnel-select-prefix-name_0'); + await page.fill('id=form-dialog-personnel-input-first-name', 'บุญมา'); + await page.fill('id=form-dialog-personnel-input-last-name', 'พามา'); + await page.fill('id=form-dialog-personnel-input-first-name-en', 'Bunma'); + await page.fill('id=form-dialog-personnel-input-last-name-en', 'Pama'); + await page.fill('id=form-dialog-personnel-input-telephone', '08422644482'); + await page.fill( + 'id=form-dialog-personnel-input-email', + 'cocustomer@mail.com', + ); + + // เลือกเพศ + await page.click('id=form-dialog-personnel-select-gender'); + await page.click("//span[text()='ชาย']"); + + // เลือกวันเกิด + await page.click('id=form-dialog-personnel-input-birth-date'); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='8']"); + + // วันออกบัตร วันที่หมออายุ + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-issue'])[1]", + ); + await page.click("//div[@id='2024-09-02']"); + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-expire'])[1]", + ); + await page.click("//div[@id='2024-09-17']/div[1]"); + + // กรอกที่อยู่ + await page.fill('id=drawer-info-personnel-input-address-no', '20/1'); + await page.click('id=drawer-info-personnel-select-province'); + await page.waitForSelector('id=drawer-info-personnel-select-province_6', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-province_6'); + await page.click('id=drawer-info-personnel-select-district'); + await page.waitForSelector('id=drawer-info-personnel-select-district_2', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-district_2'); + await page.click('id=drawer-info-personnel-select-sub-district'); + await page.waitForSelector('id=drawer-info-personnel-select-sub-district_1', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-sub-district_1'); + + // กรอกที่อยู่ภาษาอังกฤษ + await page.fill('id=drawer-info-personnel-input-address-en', '20/01'); + + // กรอกข้อมูลการทำงาน + await page.fill('id=input-regis-no', '2822282222421'); + await page.click('id=input-start-date'); + await page.click("//div[@id='2024-09-12']/div[1]"); + await page.click('id=input-retire-date'); + await page.click("//div[@id='2024-09-24']/div[1]"); + + // กดปุ่มเพื่อสร้างบุคคลากร + await page.click('id=btn-info-basic-save'); + await page.waitForTimeout(2000); + + // ดึงข้อมูลจาก Locator และนำ .textContent() เพื่อดึงมาแต่ข้อความจริง ๆ + await page.waitForSelector; + const displayNameLocator = page.locator( + "//div[normalize-space(text())='บุญมา พามา']", + ); + + const displayName = (await displayNameLocator.textContent())?.trim() || ''; + + // ตรวจสอบข้อมูลที่ดึงออกมา + expect(displayName).toBe('บุญมา พามา'); + console.log(displayName); + + console.log('ตรวจสอบการสร้างตำแหน่งงานถูกต้อง'); + await page.waitForTimeout(4000); +}); + +test('ทดสอบการเข้าใช้งาน ผู้ใช้งานสิทธิ์ Corporate Customer ', async () => { + try { + // ออกจากระบบและเข้าสู่ระบบด้วย Role ใหม่ + await page.click('id=btn-profile-menu'); + await page.click('id=btn-logout'); + await page.click('id=btn-ok-dialog'); + await page.fill("input[name='username']", 'corporatecus'); + await page.fill("input[name='password']", 'corporatecus'); + await page.click('id=kc-login'); + + // ใส่รหัสใหม่ + await page.fill('id=password-new', '1234'); + await page.fill('id=password-confirm', '1234'); + await page.click("//input[@type='submit']"); + + // กรอกอีเมลเพื่อสร้างผู้ใช้งานใหม่ + await page.fill('id=email', 'corporcu@email.com'); + await page.click("//input[@type='submit']"); + await page.waitForTimeout(2000); + + // ตรวจสอบข้อมูลหลังจากทำการเข้าสู่ระบบ + const useRole = await page + .locator("//div[normalize-space(text())='Corporate Customer']") + .textContent(); + expect(useRole?.trim()).toBe('Corporate Customer'); + + console.log('ตรวจสอบสำเร็จ : สิทธิ์ผู้ใช้งานประเภท Corporate Customer'); + + // ตรวจสอบเมนูสำหรับสิทธิ์ผู้ใช้งานประเภท Corporate Customer ปรากฏ + const menuCustomerManagement = await page.isVisible( + 'id=drawer-menu.customer', + ); + const menuProductAndService = await page.isVisible( + 'id=drawer-menu.product', + ); + const menuDocumentManagement = await page.isVisible('id=drawer-menu.dms'); + + // ตรวจสอบว่าเมนูปรากฏ + expect(menuCustomerManagement).toBe(true); + expect(menuProductAndService).toBe(true); + expect(menuDocumentManagement).toBe(true); + + console.log('ตรวจสอบเมนูต่าง ๆ ของ สิทธิ์ Corporate Cutomer สำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ', error); + throw error; + } + await page.waitForTimeout(4000); +}); diff --git a/tests/00-Role&Permission/JWS_RP_002_HeadOfAdmin.spec.ts b/tests/00-Role&Permission/JWS_RP_002_HeadOfAdmin.spec.ts new file mode 100644 index 00000000..2f15e88f --- /dev/null +++ b/tests/00-Role&Permission/JWS_RP_002_HeadOfAdmin.spec.ts @@ -0,0 +1,185 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; +import { Console, error, log } from 'console'; +import { waitForDebugger } from 'inspector'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Create Personnel - ตำแหน่ง Head of Admin', async () => { + await page.click('id=menu-icon-personnel-management'); + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + + // กรอกข้อมูลพื้นฐานของบุคคลากร + await page.click("//i[@aria-hidden='false']"); + await page.waitForSelector('id=select-hq-id', { + state: 'visible', + }); + await page.click('id=select-hq-id'); + await page.click("//span[normalize-space(text())='CMO00000']"); + await page.waitForSelector('id=select-br-id', { state: 'visible' }); + await page.click('id=select-br-id'); + await page.click('id=select-br-id_4'); + await page.fill('id=input-username', 'headofad'); + await page.click('id=select-user-type'); + await page.click('id=select-user-type_0'); + await page.click('id=select-user-role'); + await page.click('id=select-user-role_1'); + // await page.click("//div[@role='option']"); + + // กรอกชื่อข้อมูลพื้นฐาน + await page.fill('id=input-citizen-id', '1282262422820'); + await page.click("//label[@for='form-dialog-personnel-select-prefix-name']"); + await page.click('id=form-dialog-personnel-select-prefix-name_0'); + await page.fill('id=form-dialog-personnel-input-first-name', 'ธนินทร์'); + await page.fill('id=form-dialog-personnel-input-last-name', 'ประเสริฐปัตตนา'); + await page.fill('id=form-dialog-personnel-input-first-name-en', 'Thanin'); + await page.fill( + 'id=form-dialog-personnel-input-last-name-en', + 'Prasertpattana', + ); + await page.fill('id=form-dialog-personnel-input-telephone', '08422644482'); + await page.fill('id=form-dialog-personnel-input-email', 'hoa@mail.com'); + + // เลือกเพศ + await page.click('id=form-dialog-personnel-select-gender'); + await page.click("//span[text()='ชาย']"); + + // เลือกวันเกิด + await page.click('id=form-dialog-personnel-input-birth-date'); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='8']"); + + // วันออกบัตร วันที่หมออายุ + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-issue'])[1]", + ); + await page.click("//div[@id='2024-09-02']"); + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-expire'])[1]", + ); + await page.click("//div[@id='2024-09-17']/div[1]"); + + // กรอกที่อยู่ + await page.fill('id=drawer-info-personnel-input-address-no', '20/1'); + await page.click('id=drawer-info-personnel-select-province'); + await page.waitForSelector('id=drawer-info-personnel-select-province_6', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-province_6'); + await page.click('id=drawer-info-personnel-select-district'); + await page.waitForSelector('id=drawer-info-personnel-select-district_2', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-district_2'); + await page.click('id=drawer-info-personnel-select-sub-district'); + await page.waitForSelector('id=drawer-info-personnel-select-sub-district_1', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-sub-district_1'); + + // กรอกที่อยู่ภาษาอังกฤษ + await page.fill('id=drawer-info-personnel-input-address-en', '20/01'); + + // กรอกข้อมูลการทำงาน + await page.fill('id=input-regis-no', '2822282222421'); + await page.click('id=input-start-date'); + await page.click("//div[@id='2024-09-12']/div[1]"); + await page.click('id=input-retire-date'); + await page.click("//div[@id='2024-09-16']/div[1]"); + + // กดปุ่มเพื่อสร้างบุคคลากร + await page.click('id=btn-info-basic-save'); + await page.waitForTimeout(2000); + + // ดึงข้อมูลจาก Locator และนำ .textContent() เพื่อดึงมาแต่ข้อความจริง ๆ + await page.waitForSelector; + const displayNameLocator = page.locator( + "//div[normalize-space(text())='ธนินทร์ ประเสริฐปัตตนา']", + ); + + const displayName = (await displayNameLocator.textContent())?.trim() || ''; + + // ตรวจสอบข้อมูลที่ดึงออกมา + expect(displayName).toBe('ธนินทร์ ประเสริฐปัตตนา'); + console.log(displayName); + + console.log('ตรวจสอบการสร้างตำแหน่งงานถูกต้อง'); + await page.waitForTimeout(4000); +}); + +test('ทดสอบการเข้าใช้งาน ผู้ใช้งานสิทธิ์ Head of Admin ', async () => { + try { + // ออกจากระบบและเข้าสู่ระบบด้วย Role ใหม่ + await page.click('id=btn-profile-menu'); + await page.click('id=btn-logout'); + await page.click('id=btn-ok-dialog'); + await page.fill("input[name='username']", 'headofad'); + await page.fill("input[name='password']", 'headofad'); + await page.click('id=kc-login'); + + // ใส่รหัสใหม่ + await page.fill('id=password-new', '1234'); + await page.fill('id=password-confirm', '1234'); + await page.click("//input[@type='submit']"); + + // กรอกอีเมลเพื่อสร้างผู้ใช้งานใหม่ + await page.fill('id=email', 'headofadmin@email.com'); + await page.click("//input[@type='submit']"); + await page.waitForTimeout(2000); + + // ตรวจสอบข้อมูลหลังจากทำการเข้าสู่ระบบ + const useRole = await page + .locator("//div[normalize-space(text())='Head Of Admin']") + .textContent(); + expect(useRole?.trim()).toBe('Head Of Admin'); + + console.log('ตรวจสอบสำเร็จ : สิทธิ์ผู้ใช้งานประเภท Head of Admin'); + + // ตรวจสอบเมนูสำหรับสิทธิ์ผู้ใช้งานประเภท Head of Admin ปรากฏ + const menuBranchManagement = await page.isVisible('id=drawer-menu.branch'); + const menuPersonnelManagement = await page.isVisible('id=drawer-menu.user'); + const menuCustomerManagement = await page.isVisible( + 'id=drawer-menu.customer', + ); + const menuProductAndService = await page.isVisible( + 'id=drawer-menu.product', + ); + const menuDocumentManagement = await page.isVisible('id=drawer-menu.dms'); + + // ตรวจสอบว่าเมนูปรากฏ + expect(menuBranchManagement).toBe(true); + expect(menuPersonnelManagement).toBe(true); + expect(menuCustomerManagement).toBe(true); + expect(menuProductAndService).toBe(true); + expect(menuDocumentManagement).toBe(true); + + console.log('ตรวจสอบเมนูต่าง ๆ ของ สิทธิ์ Head of Admin สำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ', error); + throw error; + } + await page.waitForTimeout(4000); +}); diff --git a/tests/00-Role&Permission/JWS_RP_003_Sale.spec.ts b/tests/00-Role&Permission/JWS_RP_003_Sale.spec.ts new file mode 100644 index 00000000..4596dd0c --- /dev/null +++ b/tests/00-Role&Permission/JWS_RP_003_Sale.spec.ts @@ -0,0 +1,184 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; +import { Console, error, log } from 'console'; +import { waitForDebugger } from 'inspector'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Create Personnel - ตำแหน่ง Sale', async () => { + await page.click('id=menu-icon-personnel-management'); + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + + // กรอกข้อมูลพื้นฐานของบุคคลากร + await page.click("//i[@aria-hidden='false']"); + await page.waitForSelector('id=select-hq-id', { + state: 'visible', + }); + await page.click('id=select-hq-id'); + await page.click("//span[normalize-space(text())='CMO00000']"); + await page.waitForSelector('id=select-br-id', { state: 'visible' }); + await page.click('id=select-br-id'); + await page.click('id=select-br-id_4'); + await page.fill('id=input-username', 'sale'); + await page.click('id=select-user-type'); + await page.click('id=select-user-type_0'); + await page.click('id=select-user-role'); + await page.click('id=select-user-role_2'); + // await page.click("//div[@role='option']"); + + // กรอกชื่อข้อมูลพื้นฐาน + await page.fill('id=input-citizen-id', '1282262422820'); + await page.click("//label[@for='form-dialog-personnel-select-prefix-name']"); + await page.click('id=form-dialog-personnel-select-prefix-name_0'); + await page.fill('id=form-dialog-personnel-input-first-name', 'เกียรติ'); + await page.fill( + 'id=form-dialog-personnel-input-last-name', + 'อินทรประสิทธิ์ ', + ); + await page.fill('id=form-dialog-personnel-input-first-name-en', 'Kiat'); + await page.fill( + 'id=form-dialog-personnel-input-last-name-en', + 'Intaraprasith', + ); + await page.fill('id=form-dialog-personnel-input-telephone', '08422644482'); + await page.fill('id=form-dialog-personnel-input-email', 'sale@mail.com'); + + // เลือกเพศ + await page.click('id=form-dialog-personnel-select-gender'); + await page.click("//span[text()='ชาย']"); + + // เลือกวันเกิด + await page.click('id=form-dialog-personnel-input-birth-date'); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='8']"); + + // วันออกบัตร วันที่หมออายุ + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-issue'])[1]", + ); + await page.click("//div[@id='2024-09-02']"); + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-expire'])[1]", + ); + await page.click("//div[@id='2024-09-17']/div[1]"); + + // กรอกที่อยู่ + await page.fill('id=drawer-info-personnel-input-address-no', '20/1'); + await page.click('id=drawer-info-personnel-select-province'); + await page.waitForSelector('id=drawer-info-personnel-select-province_6', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-province_6'); + await page.click('id=drawer-info-personnel-select-district'); + await page.waitForSelector('id=drawer-info-personnel-select-district_2', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-district_2'); + await page.click('id=drawer-info-personnel-select-sub-district'); + await page.waitForSelector('id=drawer-info-personnel-select-sub-district_1', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-sub-district_1'); + + // กรอกที่อยู่ภาษาอังกฤษ + await page.fill('id=drawer-info-personnel-input-address-en', '20/01'); + + // กรอกข้อมูลการทำงาน + await page.fill('id=input-regis-no', '2822282222421'); + await page.click('id=input-start-date'); + await page.click("//div[@id='2024-09-12']/div[1]"); + await page.click('id=input-retire-date'); + await page.click("//div[@id='2024-09-16']/div[1]"); + + // กดปุ่มเพื่อสร้างบุคคลากร + await page.click('id=btn-info-basic-save'); + await page.waitForTimeout(2000); + + // ดึงข้อมูลจาก Locator และนำ .textContent() เพื่อดึงมาแต่ข้อความจริง ๆ + await page.waitForSelector; + const displayNameLocator = page.locator( + "//div[normalize-space(text())='เกียรติ อินทรประสิทธิ์']", + ); + + const displayName = (await displayNameLocator.textContent())?.trim() || ''; + + // ตรวจสอบข้อมูลที่ดึงออกมา + expect(displayName).toBe('เกียรติ อินทรประสิทธิ์'); + console.log(displayName); + + console.log('ตรวจสอบการสร้างตำแหน่งงานถูกต้อง'); + await page.waitForTimeout(4000); +}); + +test('ทดสอบการเข้าใช้งาน ผู้ใช้งานสิทธิ์ Sale ', async () => { + try { + // ออกจากระบบและเข้าสู่ระบบด้วย Role ใหม่ + await page.click('id=btn-profile-menu'); + await page.click('id=btn-logout'); + await page.click('id=btn-ok-dialog'); + await page.fill("input[name='username']", 'sale'); + await page.fill("input[name='password']", 'sale'); + await page.click('id=kc-login'); + + // ใส่รหัสใหม่ + await page.fill('id=password-new', '1234'); + await page.fill('id=password-confirm', '1234'); + await page.click("//input[@type='submit']"); + + // กรอกอีเมลเพื่อสร้างผู้ใช้งานใหม่ + await page.fill('id=email', 'sale@email.com'); + await page.click("//input[@type='submit']"); + await page.waitForTimeout(2000); + + // ตรวจสอบข้อมูลหลังจากทำการเข้าสู่ระบบ + const useRole = await page + .locator("//div[normalize-space(text())='Sale']") + .textContent(); + expect(useRole?.trim()).toBe('Sale'); + + console.log('ตรวจสอบสำเร็จ : สิทธิ์ผู้ใช้งานประเภท Sale'); + + // ตรวจสอบเมนูสำหรับสิทธิ์ผู้ใช้งานประเภท Sale ปรากฏ + const menuCustomerManagement = await page.isVisible( + 'id=drawer-menu.customer', + ); + const menuProductAndService = await page.isVisible( + 'id=drawer-menu.product', + ); + const menuDocumentManagement = await page.isVisible('id=drawer-menu.dms'); + + // ตรวจสอบว่าเมนูปรากฏ + expect(menuCustomerManagement).toBe(true); + expect(menuProductAndService).toBe(true); + expect(menuDocumentManagement).toBe(true); + + console.log('ตรวจสอบเมนูต่าง ๆ ของ สิทธิ์ Sale สำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ', error); + throw error; + } + await page.waitForTimeout(4000); +}); diff --git a/tests/00-Role&Permission/JWS_RP_004_DocumentChecker.spec.ts b/tests/00-Role&Permission/JWS_RP_004_DocumentChecker.spec.ts new file mode 100644 index 00000000..e622330e --- /dev/null +++ b/tests/00-Role&Permission/JWS_RP_004_DocumentChecker.spec.ts @@ -0,0 +1,178 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; +import { Console, error, log } from 'console'; +import { waitForDebugger } from 'inspector'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Create Personnel - ตำแหน่ง Document Checker', async () => { + await page.click('id=menu-icon-personnel-management'); + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + + // กรอกข้อมูลพื้นฐานของบุคคลากร + await page.click("//i[@aria-hidden='false']"); + await page.waitForSelector('id=select-hq-id', { + state: 'visible', + }); + await page.click('id=select-hq-id'); + await page.click("//span[normalize-space(text())='CMO00000']"); + await page.waitForSelector('id=select-br-id', { state: 'visible' }); + await page.click('id=select-br-id'); + await page.click('id=select-br-id_4'); + await page.fill('id=input-username', 'doccheck'); + await page.click('id=select-user-type'); + await page.click('id=select-user-type_0'); + await page.click('id=select-user-role'); + await page.click('id=select-user-role_3'); + // await page.click("//div[@role='option']"); + + // กรอกชื่อข้อมูลพื้นฐาน + await page.fill('id=input-citizen-id', '1282262422820'); + await page.click("//label[@for='form-dialog-personnel-select-prefix-name']"); + await page.click('id=form-dialog-personnel-select-prefix-name_0'); + await page.fill('id=form-dialog-personnel-input-first-name', 'พสธร'); + await page.fill('id=form-dialog-personnel-input-last-name', 'เลิศวิทยา'); + await page.fill('id=form-dialog-personnel-input-first-name-en', 'Possathorn'); + await page.fill('id=form-dialog-personnel-input-last-name-en', 'Lertwittaya'); + await page.fill('id=form-dialog-personnel-input-telephone', '08422644482'); + await page.fill('id=form-dialog-personnel-input-email', 'doccheck@mail.com'); + + // เลือกเพศ + await page.click('id=form-dialog-personnel-select-gender'); + await page.click("//span[text()='ชาย']"); + + // เลือกวันเกิด + await page.click('id=form-dialog-personnel-input-birth-date'); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='8']"); + + // วันออกบัตร วันที่หมออายุ + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-issue'])[1]", + ); + await page.click("//div[@id='2024-09-02']"); + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-expire'])[1]", + ); + await page.click("//div[@id='2024-09-17']/div[1]"); + + // กรอกที่อยู่ + await page.fill('id=drawer-info-personnel-input-address-no', '20/1'); + await page.click('id=drawer-info-personnel-select-province'); + await page.waitForSelector('id=drawer-info-personnel-select-province_6', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-province_6'); + await page.click('id=drawer-info-personnel-select-district'); + await page.waitForSelector('id=drawer-info-personnel-select-district_2', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-district_2'); + await page.click('id=drawer-info-personnel-select-sub-district'); + await page.waitForSelector('id=drawer-info-personnel-select-sub-district_1', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-sub-district_1'); + + // กรอกที่อยู่ภาษาอังกฤษ + await page.fill('id=drawer-info-personnel-input-address-en', '20/01'); + + // กรอกข้อมูลการทำงาน + await page.fill('id=input-regis-no', '2822282222421'); + await page.click('id=input-start-date'); + await page.click("//div[@id='2024-09-12']/div[1]"); + await page.click('id=input-retire-date'); + await page.click("//div[@id='2024-09-16']/div[1]"); + + // กดปุ่มเพื่อสร้างบุคคลากร + await page.click('id=btn-info-basic-save'); + await page.waitForTimeout(2000); + + // ดึงข้อมูลจาก Locator และนำ .textContent() เพื่อดึงมาแต่ข้อความจริง ๆ + await page.waitForSelector; + const displayNameLocator = page.locator( + "//div[normalize-space(text())='พสธร เลิศวิทยา']", + ); + + const displayName = (await displayNameLocator.textContent())?.trim() || ''; + + // ตรวจสอบข้อมูลที่ดึงออกมา + expect(displayName).toBe('พสธร เลิศวิทยา'); + console.log(displayName); + + console.log('ตรวจสอบการสร้างตำแหน่งงานถูกต้อง'); + await page.waitForTimeout(4000); +}); + +test('ทดสอบการเข้าใช้งาน ผู้ใช้งานสิทธิ์ Document Checker ', async () => { + try { + // ออกจากระบบและเข้าสู่ระบบด้วย Role ใหม่ + await page.click('id=btn-profile-menu'); + await page.click('id=btn-logout'); + await page.click('id=btn-ok-dialog'); + await page.fill("input[name='username']", 'doccheck'); + await page.fill("input[name='password']", 'doccheck'); + await page.click('id=kc-login'); + + // ใส่รหัสใหม่ + await page.fill('id=password-new', '1234'); + await page.fill('id=password-confirm', '1234'); + await page.click("//input[@type='submit']"); + + // กรอกอีเมลเพื่อสร้างผู้ใช้งานใหม่ + await page.fill('id=email', 'docchecker@email.com'); + await page.click("//input[@type='submit']"); + await page.waitForTimeout(2000); + + // ตรวจสอบข้อมูลหลังจากทำการเข้าสู่ระบบ + const useRole = await page + .locator("//div[normalize-space(text())='Document Checker']") + .textContent(); + expect(useRole?.trim()).toBe('Document Checker'); + + console.log('ตรวจสอบสำเร็จ : สิทธิ์ผู้ใช้งานประเภท Document Checker'); + + // ตรวจสอบเมนูสำหรับสิทธิ์ผู้ใช้งานประเภท Document Checker ปรากฏ + const menuCustomerManagement = await page.isVisible( + 'id=drawer-menu.customer', + ); + const menuProductAndService = await page.isVisible( + 'id=drawer-menu.product', + ); + const menuDocumentManagement = await page.isVisible('id=drawer-menu.dms'); + + // ตรวจสอบว่าเมนูปรากฏ + expect(menuCustomerManagement).toBe(true); + expect(menuProductAndService).toBe(true); + expect(menuDocumentManagement).toBe(true); + + console.log('ตรวจสอบเมนูต่าง ๆ ของ สิทธิ์ Document Checker สำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ', error); + throw error; + } + await page.waitForTimeout(4000); +}); diff --git a/tests/00-Role&Permission/JWS_RP_005_SaleAgent.spec.ts b/tests/00-Role&Permission/JWS_RP_005_SaleAgent.spec.ts new file mode 100644 index 00000000..c3a9c094 --- /dev/null +++ b/tests/00-Role&Permission/JWS_RP_005_SaleAgent.spec.ts @@ -0,0 +1,178 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; +import { Console, error, log } from 'console'; +import { waitForDebugger } from 'inspector'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Create Personnel - ตำแหน่ง Sale Agent', async () => { + await page.click('id=menu-icon-personnel-management'); + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + + // กรอกข้อมูลพื้นฐานของบุคคลากร + await page.click("//i[@aria-hidden='false']"); + await page.waitForSelector('id=select-hq-id', { + state: 'visible', + }); + await page.click('id=select-hq-id'); + await page.click("//span[normalize-space(text())='CMO00000']"); + await page.waitForSelector('id=select-br-id', { state: 'visible' }); + await page.click('id=select-br-id'); + await page.click('id=select-br-id_4'); + await page.fill('id=input-username', 'saleag'); + await page.click('id=select-user-type'); + await page.click('id=select-user-type_0'); + await page.click('id=select-user-role'); + await page.click('id=select-user-role_4'); + // await page.click("//div[@role='option']"); + + // กรอกชื่อข้อมูลพื้นฐาน + await page.fill('id=input-citizen-id', '1282262422820'); + await page.click("//label[@for='form-dialog-personnel-select-prefix-name']"); + await page.click('id=form-dialog-personnel-select-prefix-name_0'); + await page.fill('id=form-dialog-personnel-input-first-name', 'ภาสกร'); + await page.fill('id=form-dialog-personnel-input-last-name', 'อุดมเสก'); + await page.fill('id=form-dialog-personnel-input-first-name-en', 'Passorn'); + await page.fill('id=form-dialog-personnel-input-last-name-en', 'Udomsek'); + await page.fill('id=form-dialog-personnel-input-telephone', '08422644482'); + await page.fill('id=form-dialog-personnel-input-email', 'saleag@mail.com'); + + // เลือกเพศ + await page.click('id=form-dialog-personnel-select-gender'); + await page.click("//span[text()='ชาย']"); + + // เลือกวันเกิด + await page.click('id=form-dialog-personnel-input-birth-date'); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='8']"); + + // วันออกบัตร วันที่หมออายุ + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-issue'])[1]", + ); + await page.click("//div[@id='2024-09-02']"); + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-expire'])[1]", + ); + await page.click("//div[@id='2024-09-17']/div[1]"); + + // กรอกที่อยู่ + await page.fill('id=drawer-info-personnel-input-address-no', '20/1'); + await page.click('id=drawer-info-personnel-select-province'); + await page.waitForSelector('id=drawer-info-personnel-select-province_6', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-province_6'); + await page.click('id=drawer-info-personnel-select-district'); + await page.waitForSelector('id=drawer-info-personnel-select-district_2', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-district_2'); + await page.click('id=drawer-info-personnel-select-sub-district'); + await page.waitForSelector('id=drawer-info-personnel-select-sub-district_1', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-sub-district_1'); + + // กรอกที่อยู่ภาษาอังกฤษ + await page.fill('id=drawer-info-personnel-input-address-en', '20/01'); + + // กรอกข้อมูลการทำงาน + await page.fill('id=input-regis-no', '2822282222421'); + await page.click('id=input-start-date'); + await page.click("//div[@id='2024-09-12']/div[1]"); + await page.click('id=input-retire-date'); + await page.click("//div[@id='2024-09-16']/div[1]"); + + // กดปุ่มเพื่อสร้างบุคคลากร + await page.click('id=btn-info-basic-save'); + await page.waitForTimeout(2000); + + // ดึงข้อมูลจาก Locator และนำ .textContent() เพื่อดึงมาแต่ข้อความจริง ๆ + await page.waitForSelector; + const displayNameLocator = page.locator( + "//div[normalize-space(text())='ภาสกร อุดมเสก']", + ); + + const displayName = (await displayNameLocator.textContent())?.trim() || ''; + + // ตรวจสอบข้อมูลที่ดึงออกมา + expect(displayName).toBe('ภาสกร อุดมเสก'); + console.log(displayName); + + console.log('ตรวจสอบการสร้างตำแหน่งงานถูกต้อง'); + await page.waitForTimeout(4000); +}); + +test('ทดสอบการเข้าใช้งาน ผู้ใช้งานสิทธิ์ Sale Agent ', async () => { + try { + // ออกจากระบบและเข้าสู่ระบบด้วย Role ใหม่ + await page.click('id=btn-profile-menu'); + await page.click('id=btn-logout'); + await page.click('id=btn-ok-dialog'); + await page.fill("input[name='username']", 'saleag'); + await page.fill("input[name='password']", 'saleag'); + await page.click('id=kc-login'); + + // ใส่รหัสใหม่ + await page.fill('id=password-new', '1234'); + await page.fill('id=password-confirm', '1234'); + await page.click("//input[@type='submit']"); + + // กรอกอีเมลเพื่อสร้างผู้ใช้งานใหม่ + await page.fill('id=email', 'saleag@email.com'); + await page.click("//input[@type='submit']"); + await page.waitForTimeout(2000); + + // ตรวจสอบข้อมูลหลังจากทำการเข้าสู่ระบบ + const useRole = await page + .locator("//div[normalize-space(text())='Sale Agent']") + .textContent(); + expect(useRole?.trim()).toBe('Sale Agent'); + + console.log('ตรวจสอบสำเร็จ : สิทธิ์ผู้ใช้งานประเภท Sale Agent'); + + // ตรวจสอบเมนูสำหรับสิทธิ์ผู้ใช้งานประเภท Sale Agent ปรากฏ + const menuCustomerManagement = await page.isVisible( + 'id=drawer-menu.customer', + ); + const menuProductAndService = await page.isVisible( + 'id=drawer-menu.product', + ); + const menuDocumentManagement = await page.isVisible('id=drawer-menu.dms'); + + // ตรวจสอบว่าเมนูปรากฏ + expect(menuCustomerManagement).toBe(true); + expect(menuProductAndService).toBe(true); + expect(menuDocumentManagement).toBe(true); + + console.log('ตรวจสอบเมนูต่าง ๆ ของ สิทธิ์ Sale Agent สำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ', error); + throw error; + } + await page.waitForTimeout(4000); +}); diff --git a/tests/00-Role&Permission/JWS_RP_006_Messenger.spec.ts b/tests/00-Role&Permission/JWS_RP_006_Messenger.spec.ts new file mode 100644 index 00000000..46be9fee --- /dev/null +++ b/tests/00-Role&Permission/JWS_RP_006_Messenger.spec.ts @@ -0,0 +1,178 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; +import { Console, error, log } from 'console'; +import { waitForDebugger } from 'inspector'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Create Personnel - ตำแหน่ง Messenger', async () => { + await page.click('id=menu-icon-personnel-management'); + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + + // กรอกข้อมูลพื้นฐานของบุคคลากร + await page.click("//i[@aria-hidden='false']"); + await page.waitForSelector('id=select-hq-id', { + state: 'visible', + }); + await page.click('id=select-hq-id'); + await page.click("//span[normalize-space(text())='CMO00000']"); + await page.waitForSelector('id=select-br-id', { state: 'visible' }); + await page.click('id=select-br-id'); + await page.click('id=select-br-id_4'); + await page.fill('id=input-username', 'message'); + await page.click('id=select-user-type'); + await page.click('id=select-user-type_0'); + await page.click('id=select-user-role'); + await page.click('id=select-user-role_5'); + // await page.click("//div[@role='option']"); + + // กรอกชื่อข้อมูลพื้นฐาน + await page.fill('id=input-citizen-id', '1282262422820'); + await page.click("//label[@for='form-dialog-personnel-select-prefix-name']"); + await page.click('id=form-dialog-personnel-select-prefix-name_0'); + await page.fill('id=form-dialog-personnel-input-first-name', 'ธนัท'); + await page.fill('id=form-dialog-personnel-input-last-name', 'จรัสวงศ์'); + await page.fill('id=form-dialog-personnel-input-first-name-en', 'Thanat'); + await page.fill('id=form-dialog-personnel-input-last-name-en', 'Jaraswong'); + await page.fill('id=form-dialog-personnel-input-telephone', '08422644482'); + await page.fill('id=form-dialog-personnel-input-email', 'message@mail.com'); + + // เลือกเพศ + await page.click('id=form-dialog-personnel-select-gender'); + await page.click("//span[text()='ชาย']"); + + // เลือกวันเกิด + await page.click('id=form-dialog-personnel-input-birth-date'); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='8']"); + + // วันออกบัตร วันที่หมออายุ + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-issue'])[1]", + ); + await page.click("//div[@id='2024-09-02']"); + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-expire'])[1]", + ); + await page.click("//div[@id='2024-09-17']/div[1]"); + + // กรอกที่อยู่ + await page.fill('id=drawer-info-personnel-input-address-no', '20/1'); + await page.click('id=drawer-info-personnel-select-province'); + await page.waitForSelector('id=drawer-info-personnel-select-province_6', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-province_6'); + await page.click('id=drawer-info-personnel-select-district'); + await page.waitForSelector('id=drawer-info-personnel-select-district_2', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-district_2'); + await page.click('id=drawer-info-personnel-select-sub-district'); + await page.waitForSelector('id=drawer-info-personnel-select-sub-district_1', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-sub-district_1'); + + // กรอกที่อยู่ภาษาอังกฤษ + await page.fill('id=drawer-info-personnel-input-address-en', '20/01'); + + // กรอกข้อมูลการทำงาน + await page.fill('id=input-regis-no', '2822282222421'); + await page.click('id=input-start-date'); + await page.click("//div[@id='2024-09-12']/div[1]"); + await page.click('id=input-retire-date'); + await page.click("//div[@id='2024-09-16']/div[1]"); + + // กดปุ่มเพื่อสร้างบุคคลากร + await page.click('id=btn-info-basic-save'); + await page.waitForTimeout(2000); + + // ดึงข้อมูลจาก Locator และนำ .textContent() เพื่อดึงมาแต่ข้อความจริง ๆ + await page.waitForSelector; + const displayNameLocator = page.locator( + "//div[normalize-space(text())='ธนัท จรัสวงศ์']", + ); + + const displayName = (await displayNameLocator.textContent())?.trim() || ''; + + // ตรวจสอบข้อมูลที่ดึงออกมา + expect(displayName).toBe('ธนัท จรัสวงศ์'); + console.log(displayName); + + console.log('ตรวจสอบการสร้างตำแหน่งงานถูกต้อง'); + await page.waitForTimeout(4000); +}); + +test('ทดสอบการเข้าใช้งาน ผู้ใช้งานสิทธิ์ Messenger ', async () => { + try { + // ออกจากระบบและเข้าสู่ระบบด้วย Role ใหม่ + await page.click('id=btn-profile-menu'); + await page.click('id=btn-logout'); + await page.click('id=btn-ok-dialog'); + await page.fill("input[name='username']", 'message'); + await page.fill("input[name='password']", 'message'); + await page.click('id=kc-login'); + + // ใส่รหัสใหม่ + await page.fill('id=password-new', '1234'); + await page.fill('id=password-confirm', '1234'); + await page.click("//input[@type='submit']"); + + // กรอกอีเมลเพื่อสร้างผู้ใช้งานใหม่ + await page.fill('id=email', 'message@email.com'); + await page.click("//input[@type='submit']"); + await page.waitForTimeout(2000); + + // ตรวจสอบข้อมูลหลังจากทำการเข้าสู่ระบบ + const useRole = await page + .locator("//div[normalize-space(text())='Messenger']") + .textContent(); + expect(useRole?.trim()).toBe('Messenger'); + + console.log('ตรวจสอบสำเร็จ : สิทธิ์ผู้ใช้งานประเภท Messenger'); + + // ตรวจสอบเมนูสำหรับสิทธิ์ผู้ใช้งานประเภท Messenger ปรากฏ + const menuCustomerManagement = await page.isVisible( + 'id=drawer-menu.customer', + ); + const menuProductAndService = await page.isVisible( + 'id=drawer-menu.product', + ); + const menuDocumentManagement = await page.isVisible('id=drawer-menu.dms'); + + // ตรวจสอบว่าเมนูปรากฏ + expect(menuCustomerManagement).toBe(true); + expect(menuProductAndService).toBe(true); + expect(menuDocumentManagement).toBe(true); + + console.log('ตรวจสอบเมนูต่าง ๆ ของ สิทธิ์ Messenger สำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ', error); + throw error; + } + await page.waitForTimeout(4000); +}); diff --git a/tests/00-Role&Permission/JWS_RP_007_Account.spec.ts b/tests/00-Role&Permission/JWS_RP_007_Account.spec.ts new file mode 100644 index 00000000..3f420942 --- /dev/null +++ b/tests/00-Role&Permission/JWS_RP_007_Account.spec.ts @@ -0,0 +1,176 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; +import { Console, error, log } from 'console'; +import { waitForDebugger } from 'inspector'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Create Personnel - ตำแหน่ง Account', async () => { + await page.click('id=menu-icon-personnel-management'); + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + + // กรอกข้อมูลพื้นฐานของบุคคลากร + await page.click("//i[@aria-hidden='false']"); + await page.waitForSelector('id=select-hq-id', { + state: 'visible', + }); + await page.click('id=select-hq-id'); + await page.click("//span[normalize-space(text())='CMO00000']"); + await page.waitForSelector('id=select-br-id', { state: 'visible' }); + await page.click('id=select-br-id'); + await page.click('id=select-br-id_4'); + await page.fill('id=input-username', 'account'); + await page.click('id=select-user-type'); + await page.click('id=select-user-type_0'); + await page.click('id=select-user-role'); + await page.click('id=select-user-role_6'); + // await page.click("//div[@role='option']"); + + // กรอกชื่อข้อมูลพื้นฐาน + await page.fill('id=input-citizen-id', '1282262422820'); + await page.click("//label[@for='form-dialog-personnel-select-prefix-name']"); + await page.click('id=form-dialog-personnel-select-prefix-name_0'); + await page.fill('id=form-dialog-personnel-input-first-name', 'ธาวัน'); + await page.fill('id=form-dialog-personnel-input-last-name', 'บุญดี'); + await page.fill('id=form-dialog-personnel-input-first-name-en', 'Thawan'); + await page.fill('id=form-dialog-personnel-input-last-name-en', 'Boondee'); + await page.fill('id=form-dialog-personnel-input-telephone', '08422644482'); + await page.fill('id=form-dialog-personnel-input-email', 'account@mail.com'); + + // เลือกเพศ + await page.click('id=form-dialog-personnel-select-gender'); + await page.click("//span[text()='ชาย']"); + + // เลือกวันเกิด + await page.click('id=form-dialog-personnel-input-birth-date'); + await page.click("//div[@id='2024-09-08']/div[1]"); + + // วันออกบัตร วันที่หมออายุ + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-issue'])[1]", + ); + await page.click("//div[@id='2024-09-02']"); + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-expire'])[1]", + ); + await page.click("//div[@id='2024-09-17']/div[1]"); + + // กรอกที่อยู่ + await page.fill('id=drawer-info-personnel-input-address-no', '20/1'); + await page.click('id=drawer-info-personnel-select-province'); + await page.waitForSelector('id=drawer-info-personnel-select-province_6', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-province_6'); + await page.click('id=drawer-info-personnel-select-district'); + await page.waitForSelector('id=drawer-info-personnel-select-district_2', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-district_2'); + await page.click('id=drawer-info-personnel-select-sub-district'); + await page.waitForSelector('id=drawer-info-personnel-select-sub-district_1', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-sub-district_1'); + + // กรอกที่อยู่ภาษาอังกฤษ + await page.fill('id=drawer-info-personnel-input-address-en', '20/01'); + + // กรอกข้อมูลการทำงาน + await page.fill('id=input-regis-no', '2822282222421'); + await page.click('id=input-start-date'); + await page.click("//div[@id='2024-09-12']/div[1]"); + await page.click('id=input-retire-date'); + await page.click("//div[@id='2024-09-16']/div[1]"); + + // กดปุ่มเพื่อสร้างบุคคลากร + await page.click('id=btn-info-basic-save'); + await page.waitForTimeout(2000); + + // ดึงข้อมูลจาก Locator และนำ .textContent() เพื่อดึงมาแต่ข้อความจริง ๆ + await page.waitForSelector; + const displayNameLocator = page.locator( + "//div[normalize-space(text())='ธาวัน บุญดี']", + ); + + const displayName = (await displayNameLocator.textContent())?.trim() || ''; + + // ตรวจสอบข้อมูลที่ดึงออกมา + expect(displayName).toBe('ธาวัน บุญดี'); + console.log(displayName); + + console.log('ตรวจสอบการสร้างตำแหน่งงานถูกต้อง'); + await page.waitForTimeout(4000); +}); + +test('ทดสอบการเข้าใช้งาน ผู้ใช้งานสิทธิ์ Account ', async () => { + try { + // ออกจากระบบและเข้าสู่ระบบด้วย Role ใหม่ + await page.click('id=btn-profile-menu'); + await page.click('id=btn-logout'); + await page.click('id=btn-ok-dialog'); + await page.fill("input[name='username']", 'account'); + await page.fill("input[name='password']", 'account'); + await page.click('id=kc-login'); + + // ใส่รหัสใหม่ + await page.fill('id=password-new', '1234'); + await page.fill('id=password-confirm', '1234'); + await page.click("//input[@type='submit']"); + + // กรอกอีเมลเพื่อสร้างผู้ใช้งานใหม่ + await page.fill('id=email', 'account@email.com'); + await page.click("//input[@type='submit']"); + await page.waitForTimeout(2000); + + // ตรวจสอบข้อมูลหลังจากทำการเข้าสู่ระบบ + const useRole = await page + .locator("//div[normalize-space(text())='Account']") + .textContent(); + expect(useRole?.trim()).toBe('Account'); + + console.log('ตรวจสอบสำเร็จ : สิทธิ์ผู้ใช้งานประเภท Account'); + + // ตรวจสอบเมนูสำหรับสิทธิ์ผู้ใช้งานประเภท Account ปรากฏ + const menuCustomerManagement = await page.isVisible( + 'id=drawer-menu.customer', + ); + const menuProductAndService = await page.isVisible( + 'id=drawer-menu.product', + ); + const menuDocumentManagement = await page.isVisible('id=drawer-menu.dms'); + + // ตรวจสอบว่าเมนูปรากฏ + expect(menuCustomerManagement).toBe(true); + expect(menuProductAndService).toBe(true); + expect(menuDocumentManagement).toBe(true); + + console.log('ตรวจสอบเมนูต่าง ๆ ของ สิทธิ์ Account สำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ', error); + throw error; + } + await page.waitForTimeout(4000); +}); diff --git a/tests/00-Role&Permission/JWS_RP_008_Admin.spec.ts b/tests/00-Role&Permission/JWS_RP_008_Admin.spec.ts new file mode 100644 index 00000000..64c9a00b --- /dev/null +++ b/tests/00-Role&Permission/JWS_RP_008_Admin.spec.ts @@ -0,0 +1,180 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; +import { Console, error, log } from 'console'; +import { waitForDebugger } from 'inspector'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Create Personnel - ตำแหน่ง Admin', async () => { + await page.click('id=menu-icon-personnel-management'); + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + + // กรอกข้อมูลพื้นฐานของบุคคลากร + await page.click("//i[@aria-hidden='false']"); + await page.waitForSelector('id=select-hq-id', { + state: 'visible', + }); + await page.click('id=select-hq-id'); + await page.click("//span[normalize-space(text())='CMO00000']"); + await page.waitForSelector('id=select-br-id', { state: 'visible' }); + await page.click('id=select-br-id'); + await page.click('id=select-br-id_4'); + await page.fill('id=input-username', 'admins'); + await page.click('id=select-user-type'); + await page.click('id=select-user-type_0'); + await page.click('id=select-user-role'); + await page.click('id=select-user-role_7'); + // await page.click("//div[@role='option']"); + + // กรอกชื่อข้อมูลพื้นฐาน + await page.fill('id=input-citizen-id', '1282262422820'); + await page.click("//label[@for='form-dialog-personnel-select-prefix-name']"); + await page.click('id=form-dialog-personnel-select-prefix-name_0'); + await page.fill('id=form-dialog-personnel-input-first-name', 'ธีรญาณ'); + await page.fill('id=form-dialog-personnel-input-last-name', 'สุขเกษม'); + await page.fill('id=form-dialog-personnel-input-first-name-en', 'Theerayan'); + await page.fill('id=form-dialog-personnel-input-last-name-en', 'Sukkasem'); + await page.fill('id=form-dialog-personnel-input-telephone', '08422644482'); + await page.fill('id=form-dialog-personnel-input-email', 'admin@mail.com'); + + // เลือกเพศ + await page.click('id=form-dialog-personnel-select-gender'); + await page.click("//span[text()='ชาย']"); + + // เลือกวันเกิด + await page.click('id=form-dialog-personnel-input-birth-date'); + await page.click("//div[@id='2024-09-08']/div[1]"); + + // วันออกบัตร วันที่หมออายุ + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-issue'])[1]", + ); + await page.click("//div[@id='2024-09-02']"); + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-expire'])[1]", + ); + await page.click("//div[@id='2024-09-17']/div[1]"); + + // กรอกที่อยู่ + await page.fill('id=drawer-info-personnel-input-address-no', '20/1'); + await page.click('id=drawer-info-personnel-select-province'); + await page.waitForSelector('id=drawer-info-personnel-select-province_6', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-province_6'); + await page.click('id=drawer-info-personnel-select-district'); + await page.waitForSelector('id=drawer-info-personnel-select-district_2', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-district_2'); + await page.click('id=drawer-info-personnel-select-sub-district'); + await page.waitForSelector('id=drawer-info-personnel-select-sub-district_1', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-sub-district_1'); + + // กรอกที่อยู่ภาษาอังกฤษ + await page.fill('id=drawer-info-personnel-input-address-en', '20/01'); + + // กรอกข้อมูลการทำงาน + await page.fill('id=input-regis-no', '2822282222421'); + await page.click('id=input-start-date'); + await page.click("//div[@id='2024-09-12']/div[1]"); + await page.click('id=input-retire-date'); + await page.click("//div[@id='2024-09-16']/div[1]"); + + // กดปุ่มเพื่อสร้างบุคคลากร + await page.click('id=btn-info-basic-save'); + await page.waitForTimeout(2000); + + // ดึงข้อมูลจาก Locator และนำ .textContent() เพื่อดึงมาแต่ข้อความจริง ๆ + await page.waitForSelector; + const displayNameLocator = page.locator( + "//div[normalize-space(text())='ธีรญาณ สุขเกษม']", + ); + + const displayName = (await displayNameLocator.textContent())?.trim() || ''; + + // ตรวจสอบข้อมูลที่ดึงออกมา + expect(displayName).toBe('ธีรญาณ สุขเกษม'); + console.log(displayName); + + console.log('ตรวจสอบการสร้างตำแหน่งงานถูกต้อง'); + await page.waitForTimeout(4000); +}); + +test('ทดสอบการเข้าใช้งาน ผู้ใช้งานสิทธิ์ Admin ', async () => { + try { + // ออกจากระบบและเข้าสู่ระบบด้วย Role ใหม่ + await page.click('id=btn-profile-menu'); + await page.click('id=btn-logout'); + await page.click('id=btn-ok-dialog'); + await page.fill("input[name='username']", 'admins'); + await page.fill("input[name='password']", 'admins'); + await page.click('id=kc-login'); + + // ใส่รหัสใหม่ + await page.fill('id=password-new', '1234'); + await page.fill('id=password-confirm', '1234'); + await page.click("//input[@type='submit']"); + + // กรอกอีเมลเพื่อสร้างผู้ใช้งานใหม่ + await page.fill('id=email', 'admins@email.com'); + await page.click("//input[@type='submit']"); + await page.waitForTimeout(2000); + + // ตรวจสอบข้อมูลหลังจากทำการเข้าสู่ระบบ + const useRole = await page + .locator("//div[normalize-space(text())='Admin']") + .textContent(); + expect(useRole?.trim()).toBe('Admin'); + + console.log('ตรวจสอบสำเร็จ : สิทธิ์ผู้ใช้งานประเภท Admin'); + + // ตรวจสอบเมนูสำหรับสิทธิ์ผู้ใช้งานประเภท Admin ปรากฏ + const menuBranchManagement = await page.isVisible('id=drawer-menu.branch'); + const menuPersonnelManagement = await page.isVisible('id=drawer-menu.user'); + const menuCustomerManagement = await page.isVisible( + 'id=drawer-menu.customer', + ); + const menuProductAndService = await page.isVisible( + 'id=drawer-menu.product', + ); + const menuDocumentManagement = await page.isVisible('id=drawer-menu.dms'); + + // ตรวจสอบว่าเมนูปรากฏ + expect(menuBranchManagement).toBe(true); + expect(menuPersonnelManagement).toBe(true); + expect(menuCustomerManagement).toBe(true); + expect(menuProductAndService).toBe(true); + expect(menuDocumentManagement).toBe(true); + + console.log('ตรวจสอบเมนูต่าง ๆ ของ สิทธิ์ Admin สำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ', error); + throw error; + } + await page.waitForTimeout(4000); +}); diff --git a/tests/00-Role&Permission/JWS_RP_009_Executive.spec.ts b/tests/00-Role&Permission/JWS_RP_009_Executive.spec.ts new file mode 100644 index 00000000..1500cf27 --- /dev/null +++ b/tests/00-Role&Permission/JWS_RP_009_Executive.spec.ts @@ -0,0 +1,179 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; +import { Console, error, log } from 'console'; +import { waitForDebugger } from 'inspector'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Create Personnel - ตำแหน่ง Executive', async () => { + await page.click('id=menu-icon-personnel-management'); + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + + // กรอกข้อมูลพื้นฐานของบุคคลากร + await page.click("//i[@aria-hidden='false']"); + await page.waitForSelector('id=select-hq-id', { + state: 'visible', + }); + await page.click('id=select-hq-id'); + await page.click("//span[normalize-space(text())='CMO00000']"); + await page.waitForSelector('id=select-br-id', { state: 'visible' }); + await page.click('id=select-br-id'); + await page.click('id=select-br-id_4'); + await page.fill('id=input-username', 'executive'); + await page.click('id=select-user-type'); + await page.click('id=select-user-type_0'); + await page.click('id=select-user-role'); + await page.click('id=select-user-role_8'); + // await page.click("//div[@role='option']"); + + // กรอกชื่อข้อมูลพื้นฐาน + await page.fill('id=input-citizen-id', '1282262422820'); + await page.click("//label[@for='form-dialog-personnel-select-prefix-name']"); + await page.click('id=form-dialog-personnel-select-prefix-name_0'); + await page.fill('id=form-dialog-personnel-input-first-name', 'ทีปกร'); + await page.fill('id=form-dialog-personnel-input-last-name', 'สุวรรณเวชธาดา'); + await page.fill('id=form-dialog-personnel-input-first-name-en', 'Teepakorn'); + await page.fill( + 'id=form-dialog-personnel-input-last-name-en', + 'Suwanwechatada', + ); + await page.fill('id=form-dialog-personnel-input-telephone', '08422644482'); + await page.fill('id=form-dialog-personnel-input-email', 'executive@mail.com'); + + // เลือกเพศ + await page.click('id=form-dialog-personnel-select-gender'); + await page.click("//span[text()='ชาย']"); + + // เลือกวันเกิด + await page.click('id=form-dialog-personnel-input-birth-date'); + await page.click("//div[@id='2024-09-08']/div[1]"); + + // วันออกบัตร วันที่หมออายุ + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-issue'])[1]", + ); + await page.click("//div[@id='2024-09-02']"); + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-expire'])[1]", + ); + await page.click("//div[@id='2024-09-17']/div[1]"); + + // กรอกที่อยู่ + await page.fill('id=drawer-info-personnel-input-address-no', '20/1'); + await page.click('id=drawer-info-personnel-select-province'); + await page.waitForSelector('id=drawer-info-personnel-select-province_6', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-province_6'); + await page.click('id=drawer-info-personnel-select-district'); + await page.waitForSelector('id=drawer-info-personnel-select-district_2', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-district_2'); + await page.click('id=drawer-info-personnel-select-sub-district'); + await page.waitForSelector('id=drawer-info-personnel-select-sub-district_1', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-sub-district_1'); + + // กรอกที่อยู่ภาษาอังกฤษ + await page.fill('id=drawer-info-personnel-input-address-en', '20/01'); + + // กรอกข้อมูลการทำงาน + await page.fill('id=input-regis-no', '2822282222421'); + await page.click('id=input-start-date'); + await page.click("//div[@id='2024-09-12']/div[1]"); + await page.click('id=input-retire-date'); + await page.click("//div[@id='2024-09-16']/div[1]"); + + // กดปุ่มเพื่อสร้างบุคคลากร + await page.click('id=btn-info-basic-save'); + await page.waitForTimeout(2000); + + // ดึงข้อมูลจาก Locator และนำ .textContent() เพื่อดึงมาแต่ข้อความจริง ๆ + await page.waitForSelector; + const displayNameLocator = page.locator( + "//div[normalize-space(text())='ทีปกร สุวรรณเวชธาดา']", + ); + + const displayName = (await displayNameLocator.textContent())?.trim() || ''; + + // ตรวจสอบข้อมูลที่ดึงออกมา + expect(displayName).toBe('ทีปกร สุวรรณเวชธาดา'); + console.log(displayName); + + console.log('ตรวจสอบการสร้างตำแหน่งงานถูกต้อง'); + await page.waitForTimeout(4000); +}); + +test('ทดสอบการเข้าใช้งาน ผู้ใช้งานสิทธิ์ Executive ', async () => { + try { + // ออกจากระบบและเข้าสู่ระบบด้วย Role ใหม่ + await page.click('id=btn-profile-menu'); + await page.click('id=btn-logout'); + await page.click('id=btn-ok-dialog'); + await page.fill("input[name='username']", 'executive'); + await page.fill("input[name='password']", 'executive'); + await page.click('id=kc-login'); + + // ใส่รหัสใหม่ + await page.fill('id=password-new', '1234'); + await page.fill('id=password-confirm', '1234'); + await page.click("//input[@type='submit']"); + + // กรอกอีเมลเพื่อสร้างผู้ใช้งานใหม่ + await page.fill('id=email', 'executive@email.com'); + await page.click("//input[@type='submit']"); + await page.waitForTimeout(2000); + + // ตรวจสอบข้อมูลหลังจากทำการเข้าสู่ระบบ + const useRole = await page + .locator("//div[normalize-space(text())='Executive']") + .textContent(); + expect(useRole?.trim()).toBe('Executive'); + + console.log('ตรวจสอบสำเร็จ : สิทธิ์ผู้ใช้งานประเภท Executive'); + + // ตรวจสอบเมนูสำหรับสิทธิ์ผู้ใช้งานประเภท Executive ปรากฏ + const menuCustomerManagement = await page.isVisible( + 'id=drawer-menu.customer', + ); + const menuProductAndService = await page.isVisible( + 'id=drawer-menu.product', + ); + const menuDocumentManagement = await page.isVisible('id=drawer-menu.dms'); + + // ตรวจสอบว่าเมนูปรากฏ + expect(menuCustomerManagement).toBe(true); + expect(menuProductAndService).toBe(true); + expect(menuDocumentManagement).toBe(true); + + console.log('ตรวจสอบเมนูต่าง ๆ ของ สิทธิ์ Executive สำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ', error); + throw error; + } + await page.waitForTimeout(4000); +}); diff --git a/tests/00-Role&Permission/JWS_RP_010_DataEntry.spec.ts b/tests/00-Role&Permission/JWS_RP_010_DataEntry.spec.ts new file mode 100644 index 00000000..ee6aaab5 --- /dev/null +++ b/tests/00-Role&Permission/JWS_RP_010_DataEntry.spec.ts @@ -0,0 +1,176 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; +import { Console, error, log } from 'console'; +import { waitForDebugger } from 'inspector'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Create Personnel - ตำแหน่ง Data Entry', async () => { + await page.click('id=menu-icon-personnel-management'); + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + + // กรอกข้อมูลพื้นฐานของบุคคลากร + await page.click("//i[@aria-hidden='false']"); + await page.waitForSelector('id=select-hq-id', { + state: 'visible', + }); + await page.click('id=select-hq-id'); + await page.click("//span[normalize-space(text())='CMO00000']"); + await page.waitForSelector('id=select-br-id', { state: 'visible' }); + await page.click('id=select-br-id'); + await page.click('id=select-br-id_4'); + await page.fill('id=input-username', 'dataentry'); + await page.click('id=select-user-type'); + await page.click('id=select-user-type_0'); + await page.click('id=select-user-role'); + await page.click('id=select-user-role_9'); + // await page.click("//div[@role='option']"); + + // กรอกชื่อข้อมูลพื้นฐาน + await page.fill('id=input-citizen-id', '1282262422820'); + await page.click("//label[@for='form-dialog-personnel-select-prefix-name']"); + await page.click('id=form-dialog-personnel-select-prefix-name_0'); + await page.fill('id=form-dialog-personnel-input-first-name', 'กนกพงศ์'); + await page.fill('id=form-dialog-personnel-input-last-name', 'ดุสิตวรรณ'); + await page.fill('id=form-dialog-personnel-input-first-name-en', 'Kanokpong'); + await page.fill('id=form-dialog-personnel-input-last-name-en', 'Dusitwan'); + await page.fill('id=form-dialog-personnel-input-telephone', '08422644482'); + await page.fill('id=form-dialog-personnel-input-email', 'dataen@mail.com'); + + // เลือกเพศ + await page.click('id=form-dialog-personnel-select-gender'); + await page.click("//span[text()='ชาย']"); + + // เลือกวันเกิด + await page.click('id=form-dialog-personnel-input-birth-date'); + await page.click("//div[@id='2024-09-08']/div[1]"); + + // วันออกบัตร วันที่หมออายุ + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-issue'])[1]", + ); + await page.click("//div[@id='2024-09-02']"); + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-expire'])[1]", + ); + await page.click("//div[@id='2024-09-17']/div[1]"); + + // กรอกที่อยู่ + await page.fill('id=drawer-info-personnel-input-address-no', '20/1'); + await page.click('id=drawer-info-personnel-select-province'); + await page.waitForSelector('id=drawer-info-personnel-select-province_6', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-province_6'); + await page.click('id=drawer-info-personnel-select-district'); + await page.waitForSelector('id=drawer-info-personnel-select-district_2', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-district_2'); + await page.click('id=drawer-info-personnel-select-sub-district'); + await page.waitForSelector('id=drawer-info-personnel-select-sub-district_1', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-sub-district_1'); + + // กรอกที่อยู่ภาษาอังกฤษ + await page.fill('id=drawer-info-personnel-input-address-en', '20/01'); + + // กรอกข้อมูลการทำงาน + await page.fill('id=input-regis-no', '2822282222421'); + await page.click('id=input-start-date'); + await page.click("//div[@id='2024-09-12']/div[1]"); + await page.click('id=input-retire-date'); + await page.click("//div[@id='2024-09-16']/div[1]"); + + // กดปุ่มเพื่อสร้างบุคคลากร + await page.click('id=btn-info-basic-save'); + await page.waitForTimeout(2000); + + // ดึงข้อมูลจาก Locator และนำ .textContent() เพื่อดึงมาแต่ข้อความจริง ๆ + await page.waitForSelector; + const displayNameLocator = page.locator( + "//div[normalize-space(text())='กนกพงศ์ ดุสิตวรรณ']", + ); + + const displayName = (await displayNameLocator.textContent())?.trim() || ''; + + // ตรวจสอบข้อมูลที่ดึงออกมา + expect(displayName).toBe('กนกพงศ์ ดุสิตวรรณ'); + console.log(displayName); + + console.log('ตรวจสอบการสร้างตำแหน่งงานถูกต้อง'); + await page.waitForTimeout(4000); +}); + +test('ทดสอบการเข้าใช้งาน ผู้ใช้งานสิทธิ์ Data Entry ', async () => { + try { + // ออกจากระบบและเข้าสู่ระบบด้วย Role ใหม่ + await page.click('id=btn-profile-menu'); + await page.click('id=btn-logout'); + await page.click('id=btn-ok-dialog'); + await page.fill("input[name='username']", 'dataentry'); + await page.fill("input[name='password']", 'dataentry'); + await page.click('id=kc-login'); + + // ใส่รหัสใหม่ + await page.fill('id=password-new', '1234'); + await page.fill('id=password-confirm', '1234'); + await page.click("//input[@type='submit']"); + + // กรอกอีเมลเพื่อสร้างผู้ใช้งานใหม่ + await page.fill('id=email', 'dataen@email.com'); + await page.click("//input[@type='submit']"); + await page.waitForTimeout(2000); + + // ตรวจสอบข้อมูลหลังจากทำการเข้าสู่ระบบ + const useRole = await page + .locator("//div[normalize-space(text())='Data Entry']") + .textContent(); + expect(useRole?.trim()).toBe('Data Entry'); + + console.log('ตรวจสอบสำเร็จ : สิทธิ์ผู้ใช้งานประเภท Data Entry'); + + // ตรวจสอบเมนูสำหรับสิทธิ์ผู้ใช้งานประเภท Data Entry ปรากฏ + const menuCustomerManagement = await page.isVisible( + 'id=drawer-menu.customer', + ); + const menuProductAndService = await page.isVisible( + 'id=drawer-menu.product', + ); + const menuDocumentManagement = await page.isVisible('id=drawer-menu.dms'); + + // ตรวจสอบว่าเมนูปรากฏ + expect(menuCustomerManagement).toBe(true); + expect(menuProductAndService).toBe(true); + expect(menuDocumentManagement).toBe(true); + + console.log('ตรวจสอบเมนูต่าง ๆ ของ สิทธิ์ Data Entry สำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ', error); + throw error; + } + await page.waitForTimeout(4000); +}); diff --git a/tests/00-Role&Permission/JWS_RP_011_HeadOfAccount.spec.ts b/tests/00-Role&Permission/JWS_RP_011_HeadOfAccount.spec.ts new file mode 100644 index 00000000..03198a85 --- /dev/null +++ b/tests/00-Role&Permission/JWS_RP_011_HeadOfAccount.spec.ts @@ -0,0 +1,178 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; +import { Console, error, log } from 'console'; +import { waitForDebugger } from 'inspector'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Create Personnel - ตำแหน่ง Head of Account', async () => { + await page.click('id=menu-icon-personnel-management'); + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + + // กรอกข้อมูลพื้นฐานของบุคคลากร + await page.click("//i[@aria-hidden='false']"); + await page.waitForSelector('id=select-hq-id', { + state: 'visible', + }); + await page.click('id=select-hq-id'); + await page.click("//span[normalize-space(text())='CMO00000']"); + await page.waitForSelector('id=select-br-id', { state: 'visible' }); + await page.click('id=select-br-id'); + await page.click('id=select-br-id_4'); + await page.fill('id=input-username', 'headacc'); + await page.click('id=select-user-type'); + await page.click('id=select-user-type_0'); + await page.click('id=select-user-role'); + await page.click('id=select-user-role_10'); + // await page.click("//div[@role='option']"); + + // กรอกชื่อข้อมูลพื้นฐาน + await page.fill('id=input-citizen-id', '1282262422820'); + await page.click("//label[@for='form-dialog-personnel-select-prefix-name']"); + await page.click('id=form-dialog-personnel-select-prefix-name_0'); + await page.fill('id=form-dialog-personnel-input-first-name', 'ฐิติกร'); + await page.fill('id=form-dialog-personnel-input-last-name', 'วงวรางค์'); + await page.fill('id=form-dialog-personnel-input-first-name-en', 'Thitikorn'); + await page.fill('id=form-dialog-personnel-input-last-name-en', 'Wongwarang'); + await page.fill('id=form-dialog-personnel-input-telephone', '08422644482'); + await page.fill('id=form-dialog-personnel-input-email', 'headac@mail.com'); + + // เลือกเพศ + await page.click('id=form-dialog-personnel-select-gender'); + await page.click("//span[text()='ชาย']"); + + // เลือกวันเกิด + await page.click('id=form-dialog-personnel-input-birth-date'); + await page.click("//div[@id='2024-09-08']/div[1]"); + + // วันออกบัตร วันที่หมออายุ + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-issue'])[1]", + ); + await page.click("//div[@id='2024-09-02']"); + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-expire'])[1]", + ); + await page.click("//div[@id='2024-09-17']/div[1]"); + + // กรอกที่อยู่ + await page.fill('id=drawer-info-personnel-input-address-no', '20/1'); + await page.click('id=drawer-info-personnel-select-province'); + await page.waitForSelector('id=drawer-info-personnel-select-province_6', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-province_6'); + await page.click('id=drawer-info-personnel-select-district'); + await page.waitForSelector('id=drawer-info-personnel-select-district_2', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-district_2'); + await page.click('id=drawer-info-personnel-select-sub-district'); + await page.waitForSelector('id=drawer-info-personnel-select-sub-district_1', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-sub-district_1'); + + // กรอกที่อยู่ภาษาอังกฤษ + await page.fill('id=drawer-info-personnel-input-address-en', '20/01'); + + // กรอกข้อมูลการทำงาน + await page.fill('id=input-regis-no', '2822282222421'); + await page.click('id=input-start-date'); + await page.click("//div[@id='2024-09-12']/div[1]"); + await page.click('id=input-retire-date'); + await page.click("//div[@id='2024-09-16']/div[1]"); + + // กดปุ่มเพื่อสร้างบุคคลากร + await page.click('id=btn-info-basic-save'); + await page.waitForTimeout(2000); + + // ดึงข้อมูลจาก Locator และนำ .textContent() เพื่อดึงมาแต่ข้อความจริง ๆ + await page.waitForSelector; + const displayNameLocator = page.locator( + "//div[normalize-space(text())='ฐิติกร วงวรางค์']", + ); + + const displayName = (await displayNameLocator.textContent())?.trim() || ''; + + // ตรวจสอบข้อมูลที่ดึงออกมา + expect(displayName).toBe('ฐิติกร วงวรางค์'); + console.log(displayName); + + console.log('ตรวจสอบการสร้างตำแหน่งงานถูกต้อง'); + await page.waitForTimeout(4000); +}); + +test('ทดสอบการเข้าใช้งาน ผู้ใช้งานสิทธิ์ Head of Account', async () => { + try { + // ออกจากระบบและเข้าสู่ระบบด้วย Role ใหม่ + await page.click('id=btn-profile-menu'); + await page.click('id=btn-logout'); + await page.click('id=btn-ok-dialog'); + await page.fill("input[name='username']", 'headacc'); + await page.fill("input[name='password']", 'headacc'); + await page.click('id=kc-login'); + + // ใส่รหัสใหม่ + await page.fill('id=password-new', '1234'); + await page.fill('id=password-confirm', '1234'); + await page.click("//input[@type='submit']"); + + // กรอกอีเมลเพื่อสร้างผู้ใช้งานใหม่ + await page.fill('id=email', 'headac@email.com'); + await page.click("//input[@type='submit']"); + await page.waitForTimeout(2000); + + // ตรวจสอบข้อมูลหลังจากทำการเข้าสู่ระบบ + const useRole = await page + .locator("//div[normalize-space(text())='Head Of Account']") + .textContent(); + expect(useRole?.trim()).toBe('Head Of Account'); + + console.log('ตรวจสอบสำเร็จ : สิทธิ์ผู้ใช้งานประเภท Head of Account'); + + // ตรวจสอบเมนูสำหรับสิทธิ์ผู้ใช้งานประเภท Head of Account ปรากฏ + const menuBranchManagement = await page.isVisible('id=drawer-menu.branch'); + const menuCustomerManagement = await page.isVisible( + 'id=drawer-menu.customer', + ); + const menuProductAndService = await page.isVisible( + 'id=drawer-menu.product', + ); + const menuDocumentManagement = await page.isVisible('id=drawer-menu.dms'); + + // ตรวจสอบว่าเมนูปรากฏ + expect(menuBranchManagement).toBe(true); + expect(menuCustomerManagement).toBe(true); + expect(menuProductAndService).toBe(true); + expect(menuDocumentManagement).toBe(true); + + console.log('ตรวจสอบเมนูต่าง ๆ ของ สิทธิ์ Head of Account สำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ', error); + throw error; + } + await page.waitForTimeout(4000); +}); diff --git a/tests/00-Role&Permission/JWS_RP_012_HeadOfSale.spec.ts b/tests/00-Role&Permission/JWS_RP_012_HeadOfSale.spec.ts new file mode 100644 index 00000000..47626a09 --- /dev/null +++ b/tests/00-Role&Permission/JWS_RP_012_HeadOfSale.spec.ts @@ -0,0 +1,179 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; +import { Console, error, log } from 'console'; +import { waitForDebugger } from 'inspector'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Create Personnel - ตำแหน่ง Head of Sale', async () => { + await page.click('id=menu-icon-personnel-management'); + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + + // กรอกข้อมูลพื้นฐานของบุคคลากร + await page.click("//i[@aria-hidden='false']"); + await page.waitForSelector('id=select-hq-id', { + state: 'visible', + }); + await page.click('id=select-hq-id'); + await page.click("//span[normalize-space(text())='CMO00000']"); + await page.waitForSelector('id=select-br-id', { state: 'visible' }); + await page.click('id=select-br-id'); + await page.click('id=select-br-id_4'); + await page.fill('id=input-username', 'headsale'); + await page.click('id=select-user-type'); + await page.click('id=select-user-type_0'); + await page.click('id=select-user-role'); + await page.click('id=select-user-role_11'); + // await page.click("//div[@role='option']"); + + // กรอกชื่อข้อมูลพื้นฐาน + await page.fill('id=input-citizen-id', '1282262422820'); + await page.click("//label[@for='form-dialog-personnel-select-prefix-name']"); + await page.click('id=form-dialog-personnel-select-prefix-name_0'); + await page.fill('id=form-dialog-personnel-input-first-name', 'พลภัทร'); + await page.fill('id=form-dialog-personnel-input-last-name', 'ธนเจริญกิจ'); + await page.fill('id=form-dialog-personnel-input-first-name-en', 'Polapat'); + await page.fill( + 'id=form-dialog-personnel-input-last-name-en', + 'Tanajaroenkij', + ); + await page.fill('id=form-dialog-personnel-input-telephone', '08422644482'); + await page.fill('id=form-dialog-personnel-input-email', 'headsale@mail.com'); + + // เลือกเพศ + await page.click('id=form-dialog-personnel-select-gender'); + await page.click("//span[text()='ชาย']"); + + // เลือกวันเกิด + await page.click('id=form-dialog-personnel-input-birth-date'); + await page.click("//div[@id='2024-09-08']/div[1]"); + + // วันออกบัตร วันที่หมออายุ + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-issue'])[1]", + ); + await page.click("//div[@id='2024-09-02']"); + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-expire'])[1]", + ); + await page.click("//div[@id='2024-09-17']/div[1]"); + + // กรอกที่อยู่ + await page.fill('id=drawer-info-personnel-input-address-no', '20/1'); + await page.click('id=drawer-info-personnel-select-province'); + await page.waitForSelector('id=drawer-info-personnel-select-province_6', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-province_6'); + await page.click('id=drawer-info-personnel-select-district'); + await page.waitForSelector('id=drawer-info-personnel-select-district_2', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-district_2'); + await page.click('id=drawer-info-personnel-select-sub-district'); + await page.waitForSelector('id=drawer-info-personnel-select-sub-district_1', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-sub-district_1'); + + // กรอกที่อยู่ภาษาอังกฤษ + await page.fill('id=drawer-info-personnel-input-address-en', '20/01'); + + // กรอกข้อมูลการทำงาน + await page.fill('id=input-regis-no', '2822282222421'); + await page.click('id=input-start-date'); + await page.click("//div[@id='2024-09-12']/div[1]"); + await page.click('id=input-retire-date'); + await page.click("//div[@id='2024-09-16']/div[1]"); + + // กดปุ่มเพื่อสร้างบุคคลากร + await page.click('id=btn-info-basic-save'); + await page.waitForTimeout(2000); + + // ดึงข้อมูลจาก Locator และนำ .textContent() เพื่อดึงมาแต่ข้อความจริง ๆ + await page.waitForSelector; + const displayNameLocator = page.locator( + "//div[normalize-space(text())='พลภัทร ธนเจริญกิจ']", + ); + + const displayName = (await displayNameLocator.textContent())?.trim() || ''; + + // ตรวจสอบข้อมูลที่ดึงออกมา + expect(displayName).toBe('พลภัทร ธนเจริญกิจ'); + console.log(displayName); + + console.log('ตรวจสอบการสร้างตำแหน่งงานถูกต้อง'); + await page.waitForTimeout(4000); +}); + +test('ทดสอบการเข้าใช้งาน ผู้ใช้งานสิทธิ์ Head of Sale', async () => { + try { + // ออกจากระบบและเข้าสู่ระบบด้วย Role ใหม่ + await page.click('id=btn-profile-menu'); + await page.click('id=btn-logout'); + await page.click('id=btn-ok-dialog'); + await page.fill("input[name='username']", 'headsale'); + await page.fill("input[name='password']", 'headsale'); + await page.click('id=kc-login'); + + // ใส่รหัสใหม่ + await page.fill('id=password-new', '1234'); + await page.fill('id=password-confirm', '1234'); + await page.click("//input[@type='submit']"); + + // กรอกอีเมลเพื่อสร้างผู้ใช้งานใหม่ + await page.fill('id=email', 'headsale@email.com'); + await page.click("//input[@type='submit']"); + await page.waitForTimeout(2000); + + // ตรวจสอบข้อมูลหลังจากทำการเข้าสู่ระบบ + const useRole = await page + .locator("//div[normalize-space(text())='Head Of Sale']") + .textContent(); + expect(useRole?.trim()).toBe('Head Of Sale'); + + console.log('ตรวจสอบสำเร็จ : สิทธิ์ผู้ใช้งานประเภท Head of Sale'); + + // ตรวจสอบเมนูสำหรับสิทธิ์ผู้ใช้งานประเภท Head of Sale ปรากฏ + const menuCustomerManagement = await page.isVisible( + 'id=drawer-menu.customer', + ); + const menuProductAndService = await page.isVisible( + 'id=drawer-menu.product', + ); + const menuDocumentManagement = await page.isVisible('id=drawer-menu.dms'); + + // ตรวจสอบว่าเมนูปรากฏ + expect(menuCustomerManagement).toBe(true); + expect(menuProductAndService).toBe(true); + expect(menuDocumentManagement).toBe(true); + + console.log('ตรวจสอบเมนูต่าง ๆ ของ สิทธิ์ Head of Sale สำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ', error); + throw error; + } + await page.waitForTimeout(4000); +}); diff --git a/tests/00-Role&Permission/JWS_RP_013_PersonalCustomer.spec.ts b/tests/00-Role&Permission/JWS_RP_013_PersonalCustomer.spec.ts new file mode 100644 index 00000000..c203fc0b --- /dev/null +++ b/tests/00-Role&Permission/JWS_RP_013_PersonalCustomer.spec.ts @@ -0,0 +1,179 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; +import { Console, error, log } from 'console'; +import { waitForDebugger } from 'inspector'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Create Personnel - ตำแหน่ง Personal Customer', async () => { + await page.click('id=menu-icon-personnel-management'); + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + + // กรอกข้อมูลพื้นฐานของบุคคลากร + await page.click("//i[@aria-hidden='false']"); + await page.waitForSelector('id=select-hq-id', { + state: 'visible', + }); + await page.click('id=select-hq-id'); + await page.click("//span[normalize-space(text())='CMO00000']"); + await page.waitForSelector('id=select-br-id', { state: 'visible' }); + await page.click('id=select-br-id'); + await page.click('id=select-br-id_4'); + await page.fill('id=input-username', 'personal'); + await page.click('id=select-user-type'); + await page.click('id=select-user-type_0'); + await page.click('id=select-user-role'); + await page.click('id=select-user-role_12'); + // await page.click("//div[@role='option']"); + + // กรอกชื่อข้อมูลพื้นฐาน + await page.fill('id=input-citizen-id', '1282262422820'); + await page.click("//label[@for='form-dialog-personnel-select-prefix-name']"); + await page.click('id=form-dialog-personnel-select-prefix-name_0'); + await page.fill('id=form-dialog-personnel-input-first-name', 'ทีปกร'); + await page.fill('id=form-dialog-personnel-input-last-name', 'จันทรประการ'); + await page.fill('id=form-dialog-personnel-input-first-name-en', 'Teepakorn'); + await page.fill( + 'id=form-dialog-personnel-input-last-name-en', + 'Jantaraprakarn', + ); + await page.fill('id=form-dialog-personnel-input-telephone', '08422644482'); + await page.fill('id=form-dialog-personnel-input-email', 'personal@mail.com'); + + // เลือกเพศ + await page.click('id=form-dialog-personnel-select-gender'); + await page.click("//span[text()='ชาย']"); + + // เลือกวันเกิด + await page.click('id=form-dialog-personnel-input-birth-date'); + await page.click("//div[@id='2024-09-08']/div[1]"); + + // วันออกบัตร วันที่หมออายุ + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-issue'])[1]", + ); + await page.click("//div[@id='2024-09-02']"); + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-expire'])[1]", + ); + await page.click("//div[@id='2024-09-17']/div[1]"); + + // กรอกที่อยู่ + await page.fill('id=drawer-info-personnel-input-address-no', '20/1'); + await page.click('id=drawer-info-personnel-select-province'); + await page.waitForSelector('id=drawer-info-personnel-select-province_6', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-province_6'); + await page.click('id=drawer-info-personnel-select-district'); + await page.waitForSelector('id=drawer-info-personnel-select-district_2', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-district_2'); + await page.click('id=drawer-info-personnel-select-sub-district'); + await page.waitForSelector('id=drawer-info-personnel-select-sub-district_1', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-sub-district_1'); + + // กรอกที่อยู่ภาษาอังกฤษ + await page.fill('id=drawer-info-personnel-input-address-en', '20/01'); + + // กรอกข้อมูลการทำงาน + await page.fill('id=input-regis-no', '2822282222421'); + await page.click('id=input-start-date'); + await page.click("//div[@id='2024-09-12']/div[1]"); + await page.click('id=input-retire-date'); + await page.click("//div[@id='2024-09-16']/div[1]"); + + // กดปุ่มเพื่อสร้างบุคคลากร + await page.click('id=btn-info-basic-save'); + await page.waitForTimeout(2000); + + // ดึงข้อมูลจาก Locator และนำ .textContent() เพื่อดึงมาแต่ข้อความจริง ๆ + await page.waitForSelector; + const displayNameLocator = page.locator( + "//div[normalize-space(text())='ทีปกร จันทรประการ']", + ); + + const displayName = (await displayNameLocator.textContent())?.trim() || ''; + + // ตรวจสอบข้อมูลที่ดึงออกมา + expect(displayName).toBe('ทีปกร จันทรประการ'); + console.log(displayName); + + console.log('ตรวจสอบการสร้างตำแหน่งงานถูกต้อง'); + await page.waitForTimeout(4000); +}); + +test('ทดสอบการเข้าใช้งาน ผู้ใช้งานสิทธิ์ Personal Customer', async () => { + try { + // ออกจากระบบและเข้าสู่ระบบด้วย Role ใหม่ + await page.click('id=btn-profile-menu'); + await page.click('id=btn-logout'); + await page.click('id=btn-ok-dialog'); + await page.fill("input[name='username']", 'personal'); + await page.fill("input[name='password']", 'personal'); + await page.click('id=kc-login'); + + // ใส่รหัสใหม่ + await page.fill('id=password-new', '1234'); + await page.fill('id=password-confirm', '1234'); + await page.click("//input[@type='submit']"); + + // กรอกอีเมลเพื่อสร้างผู้ใช้งานใหม่ + await page.fill('id=email', 'personal@email.com'); + await page.click("//input[@type='submit']"); + await page.waitForTimeout(2000); + + // ตรวจสอบข้อมูลหลังจากทำการเข้าสู่ระบบ + const useRole = await page + .locator("//div[normalize-space(text())='Personal Customer']") + .textContent(); + expect(useRole?.trim()).toBe('Personal Customer'); + + console.log('ตรวจสอบสำเร็จ : สิทธิ์ผู้ใช้งานประเภท Personal Customer'); + + // ตรวจสอบเมนูสำหรับสิทธิ์ผู้ใช้งานประเภท Personal Customer ปรากฏ + const menuCustomerManagement = await page.isVisible( + 'id=drawer-menu.customer', + ); + const menuProductAndService = await page.isVisible( + 'id=drawer-menu.product', + ); + const menuDocumentManagement = await page.isVisible('id=drawer-menu.dms'); + + // ตรวจสอบว่าเมนูปรากฏ + expect(menuCustomerManagement).toBe(true); + expect(menuProductAndService).toBe(true); + expect(menuDocumentManagement).toBe(true); + + console.log('ตรวจสอบเมนูต่าง ๆ ของ สิทธิ์ Personal Customer สำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ', error); + throw error; + } + await page.waitForTimeout(4000); +}); diff --git a/tests/00-Role&Permission/JWS_RP_014_BranchManager.spec.ts b/tests/00-Role&Permission/JWS_RP_014_BranchManager.spec.ts new file mode 100644 index 00000000..fe1d079c --- /dev/null +++ b/tests/00-Role&Permission/JWS_RP_014_BranchManager.spec.ts @@ -0,0 +1,178 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; +import { Console, error, log } from 'console'; +import { waitForDebugger } from 'inspector'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Create Personnel - ตำแหน่ง Branch Manager', async () => { + await page.click('id=menu-icon-personnel-management'); + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + + // กรอกข้อมูลพื้นฐานของบุคคลากร + await page.click("//i[@aria-hidden='false']"); + await page.waitForSelector('id=select-hq-id', { + state: 'visible', + }); + await page.click('id=select-hq-id'); + await page.click("//span[normalize-space(text())='CMO00000']"); + await page.waitForSelector('id=select-br-id', { state: 'visible' }); + await page.click('id=select-br-id'); + await page.click('id=select-br-id_4'); + await page.fill('id=input-username', 'branch'); + await page.click('id=select-user-type'); + await page.click('id=select-user-type_0'); + await page.click('id=select-user-role'); + await page.click('id=select-user-role_13'); + // await page.click("//div[@role='option']"); + + // กรอกชื่อข้อมูลพื้นฐาน + await page.fill('id=input-citizen-id', '1282262422820'); + await page.click("//label[@for='form-dialog-personnel-select-prefix-name']"); + await page.click('id=form-dialog-personnel-select-prefix-name_0'); + await page.fill('id=form-dialog-personnel-input-first-name', 'จิรัณ'); + await page.fill('id=form-dialog-personnel-input-last-name', 'ดุสิตวรรณ'); + await page.fill('id=form-dialog-personnel-input-first-name-en', 'Jiran'); + await page.fill('id=form-dialog-personnel-input-last-name-en', 'Dusitwan'); + await page.fill('id=form-dialog-personnel-input-telephone', '08422644482'); + await page.fill('id=form-dialog-personnel-input-email', 'branch@mail.com'); + + // เลือกเพศ + await page.click('id=form-dialog-personnel-select-gender'); + await page.click("//span[text()='ชาย']"); + + // เลือกวันเกิด + await page.click('id=form-dialog-personnel-input-birth-date'); + await page.click("//div[@id='2024-09-08']/div[1]"); + + // วันออกบัตร วันที่หมออายุ + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-issue'])[1]", + ); + await page.click("//div[@id='2024-09-02']"); + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-expire'])[1]", + ); + await page.click("//div[@id='2024-09-17']/div[1]"); + + // กรอกที่อยู่ + await page.fill('id=drawer-info-personnel-input-address-no', '20/1'); + await page.click('id=drawer-info-personnel-select-province'); + await page.waitForSelector('id=drawer-info-personnel-select-province_6', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-province_6'); + await page.click('id=drawer-info-personnel-select-district'); + await page.waitForSelector('id=drawer-info-personnel-select-district_2', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-district_2'); + await page.click('id=drawer-info-personnel-select-sub-district'); + await page.waitForSelector('id=drawer-info-personnel-select-sub-district_1', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-sub-district_1'); + + // กรอกที่อยู่ภาษาอังกฤษ + await page.fill('id=drawer-info-personnel-input-address-en', '20/01'); + + // กรอกข้อมูลการทำงาน + await page.fill('id=input-regis-no', '2822282222421'); + await page.click('id=input-start-date'); + await page.click("//div[@id='2024-09-12']/div[1]"); + await page.click('id=input-retire-date'); + await page.click("//div[@id='2024-09-16']/div[1]"); + + // กดปุ่มเพื่อสร้างบุคคลากร + await page.click('id=btn-info-basic-save'); + await page.waitForTimeout(2000); + + // ดึงข้อมูลจาก Locator และนำ .textContent() เพื่อดึงมาแต่ข้อความจริง ๆ + await page.waitForSelector; + const displayNameLocator = page.locator( + "//div[normalize-space(text())='จิรัณ ดุสิตวรรณ']", + ); + + const displayName = (await displayNameLocator.textContent())?.trim() || ''; + + // ตรวจสอบข้อมูลที่ดึงออกมา + expect(displayName).toBe('จิรัณ ดุสิตวรรณ'); + console.log(displayName); + + console.log('ตรวจสอบการสร้างตำแหน่งงานถูกต้อง'); + await page.waitForTimeout(4000); +}); + +test('ทดสอบการเข้าใช้งาน ผู้ใช้งานสิทธิ์ Branch Manager', async () => { + try { + // ออกจากระบบและเข้าสู่ระบบด้วย Role ใหม่ + await page.click('id=btn-profile-menu'); + await page.click('id=btn-logout'); + await page.click('id=btn-ok-dialog'); + await page.fill("input[name='username']", 'branch'); + await page.fill("input[name='password']", 'branch'); + await page.click('id=kc-login'); + + // ใส่รหัสใหม่ + await page.fill('id=password-new', '1234'); + await page.fill('id=password-confirm', '1234'); + await page.click("//input[@type='submit']"); + + // กรอกอีเมลเพื่อสร้างผู้ใช้งานใหม่ + await page.fill('id=email', 'branch@email.com'); + await page.click("//input[@type='submit']"); + await page.waitForTimeout(2000); + + // ตรวจสอบข้อมูลหลังจากทำการเข้าสู่ระบบ + const useRole = await page + .locator("//div[normalize-space(text())='Branch Manager']") + .textContent(); + expect(useRole?.trim()).toBe('Branch Manager'); + + console.log('ตรวจสอบสำเร็จ : สิทธิ์ผู้ใช้งานประเภท Branch Manager'); + + // ตรวจสอบเมนูสำหรับสิทธิ์ผู้ใช้งานประเภท Branch Manager ปรากฏ + const menuPersonnelManagement = await page.isVisible('id=drawer-menu.user'); + const menuCustomerManagement = await page.isVisible( + 'id=drawer-menu.customer', + ); + const menuProductAndService = await page.isVisible( + 'id=drawer-menu.product', + ); + const menuDocumentManagement = await page.isVisible('id=drawer-menu.dms'); + + // ตรวจสอบว่าเมนูปรากฏ + expect(menuPersonnelManagement).toBe(true); + expect(menuCustomerManagement).toBe(true); + expect(menuProductAndService).toBe(true); + expect(menuDocumentManagement).toBe(true); + + console.log('ตรวจสอบเมนูต่าง ๆ ของ สิทธิ์ Branch Manager สำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ', error); + throw error; + } + await page.waitForTimeout(4000); +}); diff --git a/tests/01-Admin-BranchManagement/JWS_BM_001_CreateHeadquarters.spec.ts b/tests/01-Admin-BranchManagement/JWS_BM_001_CreateHeadquarters.spec.ts index b13f96b8..c97d3502 100644 --- a/tests/01-Admin-BranchManagement/JWS_BM_001_CreateHeadquarters.spec.ts +++ b/tests/01-Admin-BranchManagement/JWS_BM_001_CreateHeadquarters.spec.ts @@ -1,5 +1,6 @@ import { test, expect, Page } from '@playwright/test'; -import { strictEqual } from 'assert'; +import path from 'path'; +import { off } from 'process'; let page: Page; @@ -25,19 +26,167 @@ test('Login', async () => { }); test('Create Branch Managenment', async () => { - await page.click('id=menu-icon-branch-management'); - await page.click('id=hq-add-btn'); - await page.fill("(//input[@id='input-tax-no'])[2]", '1260846220284'); - await page.fill("(//input[@id='input-name'])[2]", 'สีลม'); - await page.fill("(//input[@id='input-name-en'])[2]", 'Silom'); - await page.fill("(//input[@id='input-address'])[2]", '20/02 '); - await page.click("(//div[@id='select-province'])[2]"); - await page.click("//div[@role='option']"); - await page.click("(//div[@id='select-district'])[2]"); - await page.click("//span[text()='เมือง']"); - await page.click("(//div[@id='select-sub-district'])[2]"); - await page.click("//span[text()='ช้างเผือก']"); - await page.fill("(//input[@id='input-address-en'])[2]", '20/02'); - await page.click('id=submitBtn'); + try { + await page.click('id=menu-icon-branch-management'); + await page.click('id=hq-add-btn'); + // await page.click('id=btn-Add'); + // await page.click("(//div[@class='q-avatar relative-position'])[2]"); + + // const fileInput = page.locator( + // "//div[@class='image-dialog-body']//button[1]", + // ); + // await fileInput.waitFor({ state: 'visible' }); + + // // อัปโหลดไฟล์ + // await fileInput.setInputFiles( + // '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + // ); // เปลี่ยน path ให้ตรง + + // await page.setInputFiles( + // "//div[@class='image-dialog-body']//button[1]", + // '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + // ); + // // UploadFile + + // ส่วนข้อมูลพื้นฐาน + await page.fill("(//input[@id='input-abbreviation'])[2]", 'CMM'); + await page.fill("(//input[@id='input-tax-no'])[2]", '1260846220284'); + await page.fill("(//input[@id='input-name'])[3]", 'บริษัท คาโมมายด์ จำกัด'); + await page.fill("(//input[@id='input-name-en'])[2]", 'CHAMOMIND'); + await page.fill( + "(//input[@aria-label='เลขที่ใบอนุญาต'])[2]", + '1228222822822', + ); + + // ส่วนติดต่อ + await page.fill("(//input[@id='input-email'])[2]", 'cmm@support.com'); + await page.fill("(//input[@id='input-telephone-no'])[2]", '022222262'); + await page.fill("(//input[@id='input-contact-name'])[2]", 'คุณต่อ'); + await page.fill("(//input[@id='input-contact'])[2]", '0866224228'); + await page.fill("(//input[@id='input-line-id'])[2]", 'local2024'); + + // ส่วนที่อยู่ + await page.fill("(//input[@id='default-input-address-no'])[2]", '20/02'); + await page.fill("(//input[@id='default-input-moo'])[3]", '1'); + await page.click("(//input[@id='default-select-province'])[2]"); + await page.click("//div[@role='option']"); + await page.click("(//input[@id='default-select-district'])[2]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.click("(//input[@id='default-select-sub-district'])[2]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.fill("(//input[@id='default-input-address-en'])[2]", '20/02'); + await page.fill("(//input[@aria-label='Moo'])[2]", '1'); + + //ส ส่วนบัญชีธนาคาร + await page.click("(//input[@id='select-bankbook'])[3]"); + await page.click('id=select-bankbook_1'); + await page.fill("(//input[@aria-label='เลขบัญชี'])[2]", '1202282262226'); + await page.fill("(//input[@aria-label='สาขาธนาคาร'])[2]", 'เชียงใหม่'); + await page.fill("(//input[@aria-label='ชื่อบัญชี'])[2]", 'Pongpon Kuntana'); + await page.click("(//input[@aria-label='ประเภทบัญชี'])[2]"); + await page.waitForTimeout(2000); + await page.click('id=select-bankbook_0'); + await page.click('id=btn-form-submit'); + + await page.waitForSelector('id=btn-ok-dialog'); + await page.click('id=btn-ok-dialog'); + + // ตรวจสอบความถูกต้องหลังจากทำการบันทึกสร้างสำนักงานใหญ่ + const newOfficeLocator = page.locator( + "//td[contains(.,'บริษัท คาโมมายด์ จำกัดCMM00000')]", + ); + await newOfficeLocator.waitFor({ state: 'visible' }); + + // ดึงข้อความจาก ที่ตรงกับ XPath + const newOfficeName = await newOfficeLocator.textContent(); + + // ตรวจสอบว่าเนื้อหาที่บันทึกถูกต้อง + if (newOfficeName !== null) { + const trimmedName = newOfficeName.trim(); + expect(trimmedName).toBe('บริษัท คาโมมายด์ จำกัดCMM00000'); + console.log('การตรวจสอบสำเร็จ: ข้อมูลถูกต้อง'); + } else { + throw new Error('ไม่พบข้อมูลที่บันทึกใน '); + } + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + + await page.waitForTimeout(2000); +}); + +test('Create Branch Managenment Second', async () => { + try { + // ส่วนข้อมูลพื้นฐาน + await page.click('id=hq-add-btn'); + await page.fill("(//input[@id='input-abbreviation'])[2]", 'CMO'); + await page.fill("(//input[@id='input-tax-no'])[2]", '1260846220284'); + await page.fill("(//input[@id='input-name'])[3]", 'บริษัท โคโม่ จำกัด'); + await page.fill("(//input[@id='input-name-en'])[2]", 'COMO'); + await page.fill( + "(//input[@aria-label='เลขที่ใบอนุญาต'])[2]", + '1228222822822', + ); + + // ส่วนติดต่อ + await page.fill("(//input[@id='input-email'])[2]", 'como@support.com'); + await page.fill("(//input[@id='input-telephone-no'])[2]", '022010100'); + await page.fill("(//input[@id='input-contact-name'])[2]", 'คุณอาท'); + await page.fill("(//input[@id='input-contact'])[2]", '0866224228'); + await page.fill("(//input[@id='input-line-id'])[2]", 'como20'); + + // ส่วนที่อยู่ + await page.fill("(//input[@id='default-input-address-no'])[2]", '40/04'); + await page.fill("(//input[@id='default-input-moo'])[3]", '2'); + await page.click("(//input[@id='default-select-province'])[2]"); + await page.click("//div[@role='option']"); + await page.click("(//input[@id='default-select-district'])[2]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.click("(//input[@id='default-select-sub-district'])[2]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.fill("(//input[@id='default-input-address-en'])[2]", '40/04'); + await page.fill("(//input[@aria-label='Moo'])[2]", '1'); + + // ส่วนธนาคาร + await page.click("(//input[@id='select-bankbook'])[3]"); + await page.click('id=select-bankbook_4'); + await page.fill("(//input[@aria-label='เลขบัญชี'])[2]", '2022822624262'); + await page.fill("(//input[@aria-label='สาขาธนาคาร'])[2]", 'ลำพูน'); + await page.fill("(//input[@aria-label='ชื่อบัญชี'])[2]", 'Pongpon Kuntana'); + await page.click("(//input[@aria-label='ประเภทบัญชี'])[2]"); + await page.waitForTimeout(2000); + await page.click('id=select-bankbook_0'); + await page.click('id=btn-form-submit'); + + await page.waitForSelector('id=btn-ok-dialog'); + await page.click('id=btn-ok-dialog'); + + // ตรวจสอบความถูกต้องหลังจากทำการบันทึกสร้างสำนักงานใหญ่ + const newOfficeLocator = page.locator( + "//td[contains(.,'บริษัท โคโม่ จำกัดCMO00000')]", + ); + await newOfficeLocator.waitFor({ state: 'visible' }); + + // ดึงข้อความจาก ที่ตรงกับ XPath + const newOfficeName = await newOfficeLocator.textContent(); + + // ตรวจสอบว่าเนื้อหาที่บันทึกถูกต้อง + if (newOfficeName !== null) { + const trimmedName = newOfficeName.trim(); + expect(trimmedName).toBe('บริษัท โคโม่ จำกัดCMO00000'); + console.log('การตรวจสอบสำเร็จ: ข้อมูลถูกต้อง'); + } else { + throw new Error('ไม่พบข้อมูลที่บันทึกใน '); + } + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.waitForTimeout(2000); }); diff --git a/tests/01-Admin-BranchManagement/JWS_BM_002_CreateHeadquarterFail.spec.ts b/tests/01-Admin-BranchManagement/JWS_BM_002_CreateHeadquarterFail.spec.ts index d122df9d..19bd7967 100644 --- a/tests/01-Admin-BranchManagement/JWS_BM_002_CreateHeadquarterFail.spec.ts +++ b/tests/01-Admin-BranchManagement/JWS_BM_002_CreateHeadquarterFail.spec.ts @@ -1,5 +1,6 @@ import { test, expect, Page } from '@playwright/test'; import { strictEqual } from 'assert'; +import exp from 'constants'; let page: Page; @@ -24,106 +25,122 @@ test('Login', async () => { // await page.click('id=acceptBtn'); }); -test('Create Branch Managenment Not input data', async () => { +test('Create Branch Management - ไม่มีการกรอกข้อมูล', async () => { await page.click('id=menu-icon-branch-management'); await page.click('id=hq-add-btn'); - await page.click('id=submitBtn'); + await page.click('id=btn-form-submit'); + + const abbreviationError = page.locator( + "(//div[@class='q-field__messages col'])[1]", + ); + const taxNoError = page.locator( + "(//div[@class='q-field__messages col']//div)[2]", + ); + const nameError = page.locator( + "(//div[@class='q-field__messages col']//div)[3]", + ); + const nameEnError = page.locator( + "(//div[@class='q-field__messages col']//div)[4]", + ); + const LicenseNumberError = page.locator( + "(//div[@class='q-field__messages col']//div)[5]", + ); + const addressError = page.locator( + "(//div[@class='q-field__messages col']//div)[6]", + ); + const provinceError = page.locator( + "(//div[@class='q-field__messages col']//div)[7]", + ); + const districtError = page.locator( + "(//div[@class='q-field__messages col']//div)[8]", + ); + const subDistrictError = page.locator( + "(//div[@class='q-field__messages col']//div)[9]", + ); + const addressEnError = page.locator( + "(//div[@class='q-field__messages col']//div)[10]", + ); + + await expect(abbreviationError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้', { + timeout: 2000, + }); + await expect(taxNoError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + await expect(nameError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + await expect(nameEnError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + await expect(LicenseNumberError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + await expect(addressError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + await expect(provinceError).toHaveText('โปรดเลือกจังหวัด'); + await expect(districtError).toHaveText('โปรดเลือกอำเภอ'); + await expect(subDistrictError).toHaveText('โปรดเลือกตำบล'); + await expect(addressEnError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + await page.waitForTimeout(4000); - await page.click("(//button[@id='closeDialog'])[2]"); + await page.click('id=btn-form-cancel'); + console.log('การตรวจสอบ Validation ถูกต้อง'); }); -test('Create Branch Managenment Not input Tax', async () => { +test('Create Branch Managenment - กรณีที่กรอกชื่อย่อที่ไม่ใช่ภาษาอังกฤษ', async () => { + await page.reload(); await page.click('id=hq-add-btn'); - await page.fill("(//input[@id='input-name'])[2]", 'สีลม'); - await page.fill("(//input[@id='input-name-en'])[2]", 'Silom'); - await page.fill("(//input[@id='input-address'])[2]", '20/02 '); - await page.click("(//div[@id='select-province'])[2]"); - await page.click("//div[@role='option']"); - await page.click("(//div[@id='select-district'])[2]"); - await page.click("//span[text()='เมือง']"); - await page.click("(//div[@id='select-sub-district'])[2]"); - await page.click("//span[text()='ช้างเผือก']"); - await page.fill("(//input[@id='input-address-en'])[2]", '20/02'); - await page.click('id=submitBtn'); + await page.fill("(//input[@id='input-abbreviation'])[2]", 'ภาษาไทย'); + const invalidDataabbreviationError = page.locator( + // ตรวจสอบการแสดง Validation แจ้งเตือนชื่อย่อในกรณีที่ไม่ใช้ภาษาอังกฤษ + "(//div[contains(@class,'q-field__bottom row')])[1]", + ); + + await expect(invalidDataabbreviationError).toHaveText( + 'ข้อมูลไม่ถูกต้อง โปรดใช้เฉพาะตัวอักษรภาษาอังกฤษและตัวเลขเท่านั้น', + { + timeout: 2000, + }, + ); + console.log( + 'ตรวจสอบการแสดง Vidation แจ้งเตือนในกรณีที่ไม่ใช่ภาษาอังกฤษถูกต้อง', + ); + await page.waitForTimeout(4000); - await page.click("(//button[@id='closeDialog'])[2]"); + await page.click('id=btn-form-cancel'); }); -test('Create Branch Managenment Not input Head Office Name Thai', async () => { +test('Create Branch Management - กรอกเลขนิติบุคคลในกรณีที่กรอกไม่ครบจำนวน 13 หลัก', async () => { + await page.reload(); await page.click('id=hq-add-btn'); - await page.fill("(//input[@id='input-tax-no'])[2]", '1260846220284'); - await page.fill("(//input[@id='input-name-en'])[2]", 'Silom'); - await page.fill("(//input[@id='input-address'])[2]", '20/02 '); - await page.click("(//div[@id='select-province'])[2]"); - await page.click("//div[@role='option']"); - await page.click("(//div[@id='select-district'])[2]"); - await page.click("//span[text()='เมือง']"); - await page.click("(//div[@id='select-sub-district'])[2]"); - await page.click("//span[text()='ช้างเผือก']"); - await page.fill("(//input[@id='input-address-en'])[2]", '20/02'); - await page.click('id=submitBtn'); + await page.fill("(//input[@id='input-tax-no'])[2]", '123'); + const taxNoError = page.locator( + // ตรวจสอบการแสดง Validation แจ้งเตือนชื่อย่อในกรณีที่ไม่ใช้ภาษาอังกฤษ + "(//div[@class='q-field__messages col']//div)[2]", + ); + + await expect(taxNoError).toHaveText( + 'ข้อมูลไม่ถูกต้อง กรุณากรอกให้ครบ 13 หลัก', + { + timeout: 2000, + }, + ); + console.log( + 'ตรวจสอบการแสดง Vidation แจ้งเตือนในกรณีที่กรอกทะเบียนนิติบุคคลเลขที่ไม่ครบ 13 หลัก', + ); + await page.waitForTimeout(4000); - await page.click("(//button[@id='closeDialog'])[2]"); + await page.click('id=btn-form-cancel'); }); -test('Create Branch Managenment Not input Head Office Name ENG', async () => { +test('Create Branch Management - กรอกอีเมลในกรณีที่ไม่ตรงรูปแบบอีเมล', async () => { + await page.reload(); await page.click('id=hq-add-btn'); - await page.fill("(//input[@id='input-name-en'])[2]", 'Silom'); - await page.fill("(//input[@id='input-address'])[2]", '20/02 '); - await page.click("(//div[@id='select-province'])[2]"); - await page.click("//div[@role='option']"); - await page.click("(//div[@id='select-district'])[2]"); - await page.click("//span[text()='เมือง']"); - await page.click("(//div[@id='select-sub-district'])[2]"); - await page.click("//span[text()='ช้างเผือก']"); - await page.fill("(//input[@id='input-address-en'])[2]", '20/02'); - await page.click('id=submitBtn'); - await page.waitForTimeout(4000); - await page.click("(//button[@id='closeDialog'])[2]"); -}); + await page.fill("(//input[@id='input-email'])[2]", '123'); + const emailError = page.locator( + // ตรวจสอบการแสดง Validation แจ้งเตือนในกรณีที่กรอกอีเมลไม่ถูกรูปแบบ + "(//div[@class='q-field__messages col']//div)[2]", + ); -test('Create Branch Managenment Not input Address TH ', async () => { - await page.click('id=hq-add-btn'); - await page.fill("(//input[@id='input-tax-no'])[2]", '1260846220284'); - await page.fill("(//input[@id='input-name'])[2]", 'สีลม'); - await page.fill("(//input[@id='input-name-en'])[2]", 'Silom'); - await page.click("(//div[@id='select-province'])[2]"); - await page.click("//div[@role='option']"); - await page.click("(//div[@id='select-district'])[2]"); - await page.click("//span[text()='เมือง']"); - await page.click("(//div[@id='select-sub-district'])[2]"); - await page.click("//span[text()='ช้างเผือก']"); - await page.fill("(//input[@id='input-address-en'])[2]", '20/02'); - await page.click('id=submitBtn'); - await page.waitForTimeout(4000); - await page.click("(//button[@id='closeDialog'])[2]"); -}); + await expect(emailError).toHaveText('ข้อมูลไม่ถูกต้อง', { + timeout: 2000, + }); + console.log( + 'ตรวจสอบการแสดง Vidation แจ้งเตือนในกรณีที่กรอกอีเมลไม่ถูกรูปแบบ', + ); -test('Create Branch Managenment Not input Address ENG', async () => { - await page.click('id=hq-add-btn'); - await page.fill("(//input[@id='input-tax-no'])[2]", '1260846220284'); - await page.fill("(//input[@id='input-name'])[2]", 'สีลม'); - await page.fill("(//input[@id='input-name-en'])[2]", 'Silom'); - await page.fill("(//input[@id='input-address'])[2]", '20/02 '); - await page.click("(//div[@id='select-province'])[2]"); - await page.click("//div[@role='option']"); - await page.click("(//div[@id='select-district'])[2]"); - await page.click("//span[text()='เมือง']"); - await page.click("(//div[@id='select-sub-district'])[2]"); - await page.click("//span[text()='ช้างเผือก']"); - await page.click('id=submitBtn'); await page.waitForTimeout(4000); - await page.click("(//button[@id='closeDialog'])[2]"); -}); - -test('Create Branch Managenment Not Select Province,District,Sub-District', async () => { - await page.click('id=hq-add-btn'); - await page.fill("(//input[@id='input-tax-no'])[2]", '1260846220284'); - await page.fill("(//input[@id='input-name'])[2]", 'สีลม'); - await page.fill("(//input[@id='input-name-en'])[2]", 'Silom'); - await page.fill("(//input[@id='input-address'])[2]", '20/02 '); - await page.fill("(//input[@id='input-address-en'])[2]", '20/02'); - await page.click('id=submitBtn'); - await page.waitForTimeout(4000); - await page.click("(//button[@id='closeDialog'])[2]"); + await page.click('id=btn-form-cancel'); }); diff --git a/tests/01-Admin-BranchManagement/JWS_BM_003_CreateSub-branch.spec.ts b/tests/01-Admin-BranchManagement/JWS_BM_003_CreateSub-branch.spec.ts index dd2803c1..5aade922 100644 --- a/tests/01-Admin-BranchManagement/JWS_BM_003_CreateSub-branch.spec.ts +++ b/tests/01-Admin-BranchManagement/JWS_BM_003_CreateSub-branch.spec.ts @@ -25,21 +25,88 @@ test('Login', async () => { }); test('Create Sub Branch Managenment', async () => { - await page.click('id=menu-icon-branch-management'); - for (let i = 0; i < 10; i++) { - await page.click('id=create-sub-branch-btn-สีลม'); - await page.fill("(//input[@id='input-tax-no'])[2]", `126084622028${i + 1}`); - await page.fill("(//input[@id='input-name'])[2]", `สีลม${i + 1}`); - await page.fill("(//input[@id='input-name-en'])[2]", `Silom${i + 1}`); - await page.fill("(//input[@id='input-address'])[2]", `20/0${i + 1}`); - await page.click("(//div[@id='select-province'])[2]"); - await page.click("//div[@role='option']"); - await page.click("(//div[@id='select-district'])[2]"); - await page.click("//span[text()='เมือง']"); - await page.click("(//div[@id='select-sub-district'])[2]"); - await page.click("//span[text()='ช้างเผือก']"); - await page.fill("(//input[@id='input-address-en'])[2]", `20/0${i + 1}`); - await page.click('id=submitBtn'); + try { + await page.click('id=menu-icon-branch-management'); + for (let i = 0; i < 5; i++) { + await page.click('id=create-sub-branch-btn-บริษัท โคโม่ จำกัด'); + await page.click("(//button[@type='submit'])[1]"); + + // ส่วนข้อมูลพื้นฐาน + await page.fill( + "(//input[@id='input-tax-no'])[2]", + `126084622028${i + 1}`, + ); + await page.fill("(//input[@id='input-name'])[3]", `สีลม${i + 1}`); + await page.fill("(//input[@id='input-name-en'])[2]", `Silom${i + 1}`); + await page.fill( + "(//input[@aria-label='เลขที่ใบอนุญาต'])[2]", + '1228222822822', + ); + + // ส่วนติดต่อ + await page.fill( + "(//input[@id='input-email'])[2]", + `host${i + 1}@local.co.th`, + ); + await page.fill("(//input[@id='input-telephone-no'])[2]", '022222002'); + await page.fill("(//input[@id='input-contact-name'])[2]", 'คุณอาท'); + await page.fill("(//input[@id='input-contact'])[2]", `08622864${i + 1}`); + await page.fill("(//input[@id='input-line-id'])[2]", 'company'); + + await page.fill( + "(//input[@id='default-input-address-no'])[2]", + `20/0${i + 1}`, + ); + await page.click("(//input[@id='default-select-province'])[2]"); + await page.click("//div[@role='option']"); + await page.click("(//input[@id='default-select-district'])[2]"); + await page.waitForTimeout(400); + await page.click("//div[@role='option']"); + await page.click("(//input[@id='default-select-sub-district'])[2]"); + await page.waitForTimeout(400); + await page.click("//div[@role='option']"); + await page.fill( + "(//input[@id='default-input-address-en'])[2]", + `20/0${i + 1}`, + ); + + await page.click("(//input[@id='select-bankbook'])[3]"); + await page.click(`id=select-bankbook_${i + 1}`); + await page.fill( + "(//input[@aria-label='เลขบัญชี'])[2]", + `228202002${i + 1}`, + ); + await page.fill("(//input[@aria-label='สาขาธนาคาร'])[2]", 'เชียงใหม่'); + await page.fill( + "(//input[@aria-label='ชื่อบัญชี'])[2]", + 'Pongpon Kuntana', + ); + await page.click("(//input[@aria-label='ประเภทบัญชี'])[2]"); + await page.waitForTimeout(2000); + await page.click('id=select-bankbook_0'); + + await page.click('id=btn-form-submit'); + } + + // ตรวจสอบความถูกต้องหลังจากทำการบันทึกสร้างสำนักงานใหญ่ + const subBranchErrors = ['สีลม1', 'สีลม2', 'สีลม3', 'สีลม4', 'สีลม5']; + + for (const branch of subBranchErrors) { + const subBranchErrors = page.locator( + `//div[normalize-space(text())='${branch}']`, + ); + await subBranchErrors.waitFor({ state: 'visible' }); + const newOfficeName = await subBranchErrors.textContent(); + const trimmedName = newOfficeName?.trim(); + + expect(trimmedName).toBe(branch); + } + + console.log('การตรวจสอบสำเร็จ : ข้อมูลถูกต้อง'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ', error); + throw error; } + await page.waitForTimeout(2000); }); diff --git a/tests/01-Admin-BranchManagement/JWS_BM_004_CreateSub-branchFail.spec.ts b/tests/01-Admin-BranchManagement/JWS_BM_004_CreateSub-branchFail.spec.ts index 43f89984..ebaf0c44 100644 --- a/tests/01-Admin-BranchManagement/JWS_BM_004_CreateSub-branchFail.spec.ts +++ b/tests/01-Admin-BranchManagement/JWS_BM_004_CreateSub-branchFail.spec.ts @@ -24,106 +24,93 @@ test('Login', async () => { // await page.click('id=acceptBtn'); }); -test('Create Sub-Branch Managenment Not input data', async () => { +test('Create Sub-Branch Managenment - ในกรณีที่ไม่กรอกข้อมูล', async () => { await page.click('id=menu-icon-branch-management'); - await page.click('id=create-sub-branch-btn-สีลม'); - await page.click('id=submitBtn'); + await page.click('id=create-sub-branch-btn-บริษัท โคโม่ จำกัด'); + await page.click("(//button[@type='submit'])[1]"); + await page.click('id=btn-form-submit'); + + const taxNoError = page.locator( + "(//div[@class='q-field__messages col']//div)[1]", + ); + const nameError = page.locator( + "(//div[@class='q-field__messages col']//div)[2]", + ); + const nameEnError = page.locator( + "(//div[@class='q-field__messages col']//div)[3]", + ); + const lincenseNumberError = page.locator( + "(//div[@class='q-field__messages col']//div)[4]", + ); + const addressError = page.locator( + "(//div[@class='q-field__messages col']//div)[5]", + ); + const provinceError = page.locator( + "(//div[@class='q-field__messages col']//div)[6]", + ); + const districtError = page.locator( + "(//div[@class='q-field__messages col']//div)[7]", + ); + const subDistrictError = page.locator( + "(//div[@class='q-field__messages col']//div)[8]", + ); + const addressEnError = page.locator( + "(//div[@class='q-field__messages col']//div)[9]", + ); + + await expect(taxNoError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + await expect(nameError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + await expect(nameEnError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + await expect(lincenseNumberError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + await expect(addressError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + await expect(provinceError).toHaveText('โปรดเลือกจังหวัด'); + await expect(districtError).toHaveText('โปรดเลือกอำเภอ'); + await expect(subDistrictError).toHaveText('โปรดเลือกตำบล'); + await expect(addressEnError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + await page.waitForTimeout(4000); - await page.click("(//button[@id='closeDialog'])[2]"); + await page.click('id=btn-form-cancel'); + console.log('การตรวจสอบ Validation ถูกต้อง'); }); -test('Create Sub-Branch Managenment Not input Tax', async () => { - await page.click('id=create-sub-branch-btn-สีลม'); - await page.fill("(//input[@id='input-name'])[2]", 'สีลม'); - await page.fill("(//input[@id='input-name-en'])[2]", 'Silom'); - await page.fill("(//input[@id='input-address'])[2]", '20/02 '); - await page.click("(//div[@id='select-province'])[2]"); - await page.click("//div[@role='option']"); - await page.click("(//div[@id='select-district'])[2]"); - await page.click("//span[text()='เมือง']"); - await page.click("(//div[@id='select-sub-district'])[2]"); - await page.click("//span[text()='ช้างเผือก']"); - await page.fill("(//input[@id='input-address-en'])[2]", '20/02'); - await page.click('id=submitBtn'); +test('Create Sub-Branch Managenment - ในกรณีที่กรอกทะเบียนนิติบุคคลเลขที่ไม่ครบ 13 หลัก', async () => { + await page.reload(); + await page.click('id=create-sub-branch-btn-บริษัท โคโม่ จำกัด'); + await page.click("(//button[@type='submit'])[1]"); + await page.fill("(//input[@id='input-tax-no'])[2]", '123'); + + // ตรวจสอบการแจ้งเตือนของทะเบียนนิติบุคคลเลขที่ในกรณีที่กรอกข้อมูลไม่ครบ 13 หลัก + const taxNoError = page.locator( + "(//div[@class='q-field__messages col']//div)[1]", + ); + + await expect(taxNoError).toHaveText( + 'ข้อมูลไม่ถูกต้อง กรุณากรอกให้ครบ 13 หลัก', + ); + await page.waitForTimeout(4000); - await page.click("(//button[@id='closeDialog'])[2]"); + await page.click('id=btn-form-cancel'); + console.log( + 'ตรวจสอบการแสดง Vidation แจ้งเตือนในกรณีที่กรอกทะเบียนนิติบุคคลเลขที่ไม่ครบ 13 หลักถูกต้อง', + ); }); -test('Create Sub-Branch Managenment Not input Head Office Name Thai', async () => { - await page.click('id=create-sub-branch-btn-สีลม'); - await page.fill("(//input[@id='input-tax-no'])[2]", '1260846220284'); - await page.fill("(//input[@id='input-name-en'])[2]", 'Silom'); - await page.fill("(//input[@id='input-address'])[2]", '20/02 '); - await page.click("(//div[@id='select-province'])[2]"); - await page.click("//div[@role='option']"); - await page.click("(//div[@id='select-district'])[2]"); - await page.click("//span[text()='เมือง']"); - await page.click("(//div[@id='select-sub-district'])[2]"); - await page.click("//span[text()='ช้างเผือก']"); - await page.fill("(//input[@id='input-address-en'])[2]", '20/02'); - await page.click('id=submitBtn'); - await page.waitForTimeout(4000); - await page.click("(//button[@id='closeDialog'])[2]"); -}); +test('Create Sub-Branch Managenment - กรอกอีเมลในกรณีที่ไม่ตรงรูปแบบอีเมล', async () => { + await page.reload(); + await page.click('id=create-sub-branch-btn-บริษัท โคโม่ จำกัด'); + await page.click("(//button[@type='submit'])[1]"); + await page.fill("(//input[@id='input-email'])[2]", 'email'); -test('Create Sub-Branch Managenment Not input Head Office Name ENG', async () => { - await page.click('id=create-sub-branch-btn-สีลม'); - await page.fill("(//input[@id='input-name-en'])[2]", 'Silom'); - await page.fill("(//input[@id='input-address'])[2]", '20/02 '); - await page.click("(//div[@id='select-province'])[2]"); - await page.click("//div[@role='option']"); - await page.click("(//div[@id='select-district'])[2]"); - await page.click("//span[text()='เมือง']"); - await page.click("(//div[@id='select-sub-district'])[2]"); - await page.click("//span[text()='ช้างเผือก']"); - await page.fill("(//input[@id='input-address-en'])[2]", '20/02'); - await page.click('id=submitBtn'); - await page.waitForTimeout(4000); - await page.click("(//button[@id='closeDialog'])[2]"); -}); + // ตรวจสอบการแจ้งเตือนของทะเบียนนิติบุคคลเลขที่ในกรณีที่กรอกข้อมูลไม่ครบ 13 หลัก + const emailError = page.locator( + "(//div[@class='q-field__messages col']//div)[2]", + ); -test('Create Sub-Branch Managenment Not input Address TH ', async () => { - await page.click('id=create-sub-branch-btn-สีลม'); - await page.fill("(//input[@id='input-tax-no'])[2]", '1260846220284'); - await page.fill("(//input[@id='input-name'])[2]", 'สีลม'); - await page.fill("(//input[@id='input-name-en'])[2]", 'Silom'); - await page.click("(//div[@id='select-province'])[2]"); - await page.click("//div[@role='option']"); - await page.click("(//div[@id='select-district'])[2]"); - await page.click("//span[text()='เมือง']"); - await page.click("(//div[@id='select-sub-district'])[2]"); - await page.click("//span[text()='ช้างเผือก']"); - await page.fill("(//input[@id='input-address-en'])[2]", '20/02'); - await page.click('id=submitBtn'); - await page.waitForTimeout(4000); - await page.click("(//button[@id='closeDialog'])[2]"); -}); + await expect(emailError).toHaveText('ข้อมูลไม่ถูกต้อง'); -test('Create Sub-Branch Managenment Not input Address ENG', async () => { - await page.click('id=create-sub-branch-btn-สีลม'); - await page.fill("(//input[@id='input-tax-no'])[2]", '1260846220284'); - await page.fill("(//input[@id='input-name'])[2]", 'สีลม'); - await page.fill("(//input[@id='input-name-en'])[2]", 'Silom'); - await page.fill("(//input[@id='input-address'])[2]", '20/02 '); - await page.click("(//div[@id='select-province'])[2]"); - await page.click("//div[@role='option']"); - await page.click("(//div[@id='select-district'])[2]"); - await page.click("//span[text()='เมือง']"); - await page.click("(//div[@id='select-sub-district'])[2]"); - await page.click("//span[text()='ช้างเผือก']"); - await page.click('id=submitBtn'); await page.waitForTimeout(4000); - await page.click("(//button[@id='closeDialog'])[2]"); -}); - -test('Create Sub-Branch Managenment Not Select Province,District,Sub-District', async () => { - await page.click('id=create-sub-branch-btn-สีลม'); - await page.fill("(//input[@id='input-tax-no'])[2]", '1260846220284'); - await page.fill("(//input[@id='input-name'])[2]", 'สีลม'); - await page.fill("(//input[@id='input-name-en'])[2]", 'Silom'); - await page.fill("(//input[@id='input-address'])[2]", '20/02 '); - await page.fill("(//input[@id='input-address-en'])[2]", '20/02'); - await page.click('id=submitBtn'); - await page.waitForTimeout(4000); - await page.click("(//button[@id='closeDialog'])[2]"); + await page.click('id=btn-form-cancel'); + console.log( + 'ตรวจสอบการแสดง Vidation แจ้งเตือนในกรณีที่กรอกอีเมลไม่ตรงรูปแบบถูกต้อง', + ); }); diff --git a/tests/01-Admin-BranchManagement/JWS_BM_005_CreateServicePoint.spec.ts b/tests/01-Admin-BranchManagement/JWS_BM_005_CreateServicePoint.spec.ts new file mode 100644 index 00000000..84ff0605 --- /dev/null +++ b/tests/01-Admin-BranchManagement/JWS_BM_005_CreateServicePoint.spec.ts @@ -0,0 +1,118 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Create Service Point Managenment', async () => { + try { + await page.click('id=menu-icon-branch-management'); + for (let i = 0; i < 5; i++) { + await page.click('id=create-sub-branch-btn-บริษัท คาโมมายด์ จำกัด'); + await page.click("(//button[@type='submit'])[2]"); + + // ส่วนข้อมูลพื้นฐาน + await page.fill( + "(//input[@id='input-tax-no'])[2]", + `202282628264${i + 1}`, + ); + await page.fill("(//input[@id='input-name'])[3]", `บางรัก${i + 1}`); + await page.fill("(//input[@id='input-name-en'])[2]", `Bangrak${i + 1}`); + await page.fill( + "(//input[@aria-label='เลขที่ใบอนุญาต'])[2]", + '1228222822822', + ); + + // ส่วนติดต่อ + await page.fill( + "(//input[@id='input-email'])[2]", + `cmm${i + 1}@local.co.th`, + ); + await page.fill("(//input[@id='input-telephone-no'])[2]", '022222002'); + await page.fill("(//input[@id='input-contact-name'])[2]", 'คุณอุล'); + await page.fill("(//input[@id='input-contact'])[2]", `082262286${i + 1}`); + await page.fill("(//input[@id='input-line-id'])[2]", 'cmmsupport'); + + await page.fill( + "(//input[@id='default-input-address-no'])[2]", + `40/0${i + 1}`, + ); + await page.click("(//input[@id='default-select-province'])[2]"); + await page.click("//div[@role='option']"); + await page.click("(//input[@id='default-select-district'])[2]"); + await page.waitForTimeout(400); + await page.click("//div[@role='option']"); + await page.click("(//input[@id='default-select-sub-district'])[2]"); + await page.waitForTimeout(400); + await page.click("//div[@role='option']"); + await page.fill( + "(//input[@id='default-input-address-en'])[2]", + `40/0${i + 1}`, + ); + + await page.click("(//input[@id='select-bankbook'])[3]"); + await page.click(`id=select-bankbook_${i + 1}`); + await page.fill( + "(//input[@aria-label='เลขบัญชี'])[2]", + `282264220${i + 1}`, + ); + await page.fill("(//input[@aria-label='สาขาธนาคาร'])[2]", 'ลำพูน'); + await page.fill( + "(//input[@aria-label='ชื่อบัญชี'])[2]", + 'Pongpon Kuntana', + ); + await page.click("(//input[@aria-label='ประเภทบัญชี'])[2]"); + await page.waitForTimeout(2000); + await page.click('id=select-bankbook_0'); + + await page.click('id=btn-form-submit'); + } + + // ตรวจสอบความถูกต้องหลังจากทำการบันทึกสร้างสำนักงานใหญ่ + const subBranchErrors = [ + 'บางรัก1', + 'บางรัก2', + 'บางรัก3', + 'บางรัก4', + 'บางรัก5', + ]; + + for (const branch of subBranchErrors) { + const subBranchErrors = page.locator( + `//div[normalize-space(text())='${branch}']`, + ); + await subBranchErrors.waitFor({ state: 'visible' }); + const newOfficeName = await subBranchErrors.textContent(); + const trimmedName = newOfficeName?.trim(); + + expect(trimmedName).toBe(branch); + } + + console.log('การตรวจสอบสำเร็จ : ข้อมูลถูกต้อง'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ', error); + throw error; + } + + await page.waitForTimeout(2000); +}); diff --git a/tests/01-Admin-BranchManagement/JWS_BM_005_SelectTypeBranch.spec.ts b/tests/01-Admin-BranchManagement/JWS_BM_005_SelectTypeBranch.spec.ts deleted file mode 100644 index 3749a858..00000000 --- a/tests/01-Admin-BranchManagement/JWS_BM_005_SelectTypeBranch.spec.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { test, expect, Page } from '@playwright/test'; -import { strictEqual } from 'assert'; - -let page: Page; - -test.beforeAll(async ({ browser }) => { - page = await browser.newPage(); -}); - -test.afterAll(async () => { - if (page !== undefined) { - await page.close(); - } -}); - -test('Login', async () => { - // Login - await page.goto('http://192.168.1.90:20001/'); - await expect(page).toHaveTitle(/^Sign in to /); - await page.fill("input[name='username']", 'admin'); - await page.fill("input[name='password']", '1234'); - await page.click('id=kc-login'); - await page.waitForTimeout(2000); - // await page.click('id=acceptBtn'); -}); - -test('Select Type Branch Name Out', async () => { - await page.click('id=menu-icon-branch-management'); - await page.click("//span[text()='ข้อมูลที่แสดง']"); - await page.click("(//div[@role='option'])[1]"); - await page.waitForTimeout(2000); -}); - -test('Select Type Branch Telephone No. Out', async () => { - await page.keyboard.press('Escape'); - await page.click("//span[text()='ข้อมูลที่แสดง']"); - await page.click("(//div[@role='option'])[2]"); - await page.waitForTimeout(2000); -}); -test('Select Type Branch Address Out', async () => { - await page.keyboard.press('Escape'); - await page.click("//span[text()='ข้อมูลที่แสดง']"); - await page.click("(//div[@role='option'])[3]"); - await page.waitForTimeout(2000); -}); -test('Select Type Branch Type Out', async () => { - await page.keyboard.press('Escape'); - await page.click("//span[text()='ข้อมูลที่แสดง']"); - await page.click("(//div[@role='option'])[4]"); - await page.waitForTimeout(2000); -}); - -test('Select Type Branch Status Out', async () => { - await page.keyboard.press('Escape'); - await page.click("//span[text()='ข้อมูลที่แสดง']"); - await page.click("(//div[@role='option'])[5]"); - await page.waitForTimeout(2000); -}); - -test('Select Type Branch Name In', async () => { - await page.keyboard.press('Escape'); - await page.click("//span[text()='ข้อมูลที่แสดง']"); - await page.click("(//div[@role='option'])[1]"); - await page.waitForTimeout(2000); -}); - -test('Select Type Branch Telephone No. In', async () => { - await page.keyboard.press('Escape'); - await page.click("//span[text()='ข้อมูลที่แสดง']"); - await page.click("(//div[@role='option'])[2]"); - await page.waitForTimeout(2000); -}); -test('Select Type Branch Address In', async () => { - await page.keyboard.press('Escape'); - await page.click("//span[text()='ข้อมูลที่แสดง']"); - await page.click("(//div[@role='option'])[3]"); - await page.waitForTimeout(2000); -}); -test('Select Type Branch Type In', async () => { - await page.keyboard.press('Escape'); - await page.click("//span[text()='ข้อมูลที่แสดง']"); - await page.click("(//div[@role='option'])[4]"); - await page.waitForTimeout(2000); -}); - -test('Select Type Branch Status In', async () => { - await page.keyboard.press('Escape'); - await page.click("//span[text()='ข้อมูลที่แสดง']"); - await page.click("(//div[@role='option'])[5]"); - await page.waitForTimeout(2000); -}); diff --git a/tests/01-Admin-BranchManagement/JWS_BM_006_CreateServicePointFail.spec.ts b/tests/01-Admin-BranchManagement/JWS_BM_006_CreateServicePointFail.spec.ts new file mode 100644 index 00000000..94491dc4 --- /dev/null +++ b/tests/01-Admin-BranchManagement/JWS_BM_006_CreateServicePointFail.spec.ts @@ -0,0 +1,112 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Create Service Point - ในกรณีที่ไม่กรอกข้อมูล', async () => { + await page.click('id=menu-icon-branch-management'); + await page.click('id=create-sub-branch-btn-บริษัท คาโมมายด์ จำกัด'); + await page.click("(//button[@type='submit'])[2]"); + await page.click('id=btn-form-submit'); + + const taxNoError = page.locator( + "(//div[@class='q-field__messages col']//div)[1]", + ); + const nameError = page.locator( + "(//div[@class='q-field__messages col']//div)[2]", + ); + const nameEnError = page.locator( + "(//div[@class='q-field__messages col']//div)[3]", + ); + const addressError = page.locator( + "(//div[@class='q-field__messages col']//div)[4]", + ); + const provinceError = page.locator( + "(//div[@class='q-field__messages col']//div)[5]", + ); + const districtError = page.locator( + "(//div[@class='q-field__messages col']//div)[6]", + ); + const subDistrictError = page.locator( + "(//div[@class='q-field__messages col']//div)[7]", + ); + const addressEnError = page.locator( + "(//div[@class='q-field__messages col']//div)[8]", + ); + + await expect(taxNoError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + await expect(nameError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + await expect(nameEnError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + await expect(addressError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + await expect(provinceError).toHaveText('โปรดเลือกจังหวัด'); + await expect(districtError).toHaveText('โปรดเลือกอำเภอ'); + await expect(subDistrictError).toHaveText('โปรดเลือกตำบล'); + await expect(addressEnError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + + await page.waitForTimeout(4000); + await page.click('id=btn-form-cancel'); + console.log('การตรวจสอบ Validation ถูกต้อง'); +}); + +test('Create Service Point - ในกรณีที่กรอกทะเบียนนิติบุคคลเลขที่ไม่ครบ 13 หลัก', async () => { + await page.reload(); + await page.click('id=create-sub-branch-btn-บริษัท คาโมมายด์ จำกัด'); + await page.click("(//button[@type='submit'])[2]"); + await page.fill("(//input[@id='input-tax-no'])[2]", '123'); + + // ตรวจสอบการแจ้งเตือนของทะเบียนนิติบุคคลเลขที่ในกรณีที่กรอกข้อมูลไม่ครบ 13 หลัก + const taxNoError = page.locator( + "(//div[@class='q-field__messages col']//div)[1]", + ); + + await expect(taxNoError).toHaveText( + 'ข้อมูลไม่ถูกต้อง กรุณากรอกให้ครบ 13 หลัก', + ); + + await page.waitForTimeout(4000); + await page.click('id=btn-form-cancel'); + console.log( + 'ตรวจสอบการแสดง Vidation แจ้งเตือนในกรณีที่กรอกทะเบียนนิติบุคคลเลขที่ไม่ครบ 13 หลักถูกต้อง', + ); +}); + +test('Create Service Point - กรอกอีเมลในกรณีที่ไม่ตรงรูปแบบอีเมล', async () => { + await page.reload(); + await page.click('id=create-sub-branch-btn-บริษัท คาโมมายด์ จำกัด'); + await page.click("(//button[@type='submit'])[2]"); + await page.fill("(//input[@id='input-email'])[2]", 'email'); + + // ตรวจสอบการแจ้งเตือนของทะเบียนนิติบุคคลเลขที่ในกรณีที่กรอกข้อมูลไม่ครบ 13 หลัก + const emailError = page.locator( + "(//div[@class='q-field__messages col']//div)[2]", + ); + + await expect(emailError).toHaveText('ข้อมูลไม่ถูกต้อง'); + + await page.waitForTimeout(4000); + await page.click('id=btn-form-cancel'); + console.log( + 'ตรวจสอบการแสดง Vidation แจ้งเตือนในกรณีที่กรอกอีเมลไม่ตรงรูปแบบถูกต้อง', + ); +}); diff --git a/tests/01-Admin-BranchManagement/JWS_BM_007_EditBranch.spec.ts b/tests/01-Admin-BranchManagement/JWS_BM_007_EditBranch.spec.ts deleted file mode 100644 index c17074bc..00000000 --- a/tests/01-Admin-BranchManagement/JWS_BM_007_EditBranch.spec.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { test, expect, Page } from '@playwright/test'; -import { strictEqual } from 'assert'; - -let page: Page; - -test.beforeAll(async ({ browser }) => { - page = await browser.newPage(); -}); - -test.afterAll(async () => { - if (page !== undefined) { - await page.close(); - } -}); - -test('Login', async () => { - // Login - await page.goto('http://192.168.1.90:20001/'); - await expect(page).toHaveTitle(/^Sign in to /); - await page.fill("input[name='username']", 'admin'); - await page.fill("input[name='password']", '1234'); - await page.click('id=kc-login'); - await page.waitForTimeout(2000); - // await page.click('id=acceptBtn'); -}); - -test('Edit Branch', async () => { - await page.click('id=menu-icon-branch-management'); - await page.click('id=view-detail-btn-สีลม'); - await page.click('id=view-detail-btn-สีลม-edit'); - await page.fill("(//input[@id='input-name'])[2]", 'สาทร'); - await page.fill("(//input[@id='input-name-en'])[2]", 'Sathorn'); - await page.click("(//button[@id='submitBtn'])[2]"); - await page.click('id=view-detail-btn-สาทร'); - await page.click('id=view-detail-btn-สาทร-view'); - await page.waitForTimeout(4000); -}); diff --git a/tests/01-Admin-BranchManagement/JWS_BM_007_SelectTypeBranch.spec.ts b/tests/01-Admin-BranchManagement/JWS_BM_007_SelectTypeBranch.spec.ts new file mode 100644 index 00000000..f17e51a2 --- /dev/null +++ b/tests/01-Admin-BranchManagement/JWS_BM_007_SelectTypeBranch.spec.ts @@ -0,0 +1,387 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; +import { watchFile } from 'fs'; +import { waitForDebugger } from 'inspector'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลลำดับที่', async () => { + try { + // คลิกเมนูเพื่อจัดการสาขา + await page.click('id=menu-icon-branch-management'); + + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_0'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_0'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_0'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + + await page.waitForTimeout(2000); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลชื่อ', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 2 + await page.click('id=select-field_1'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_1'); + const column1Cells = page.locator( + "//th[normalize-space(text())='สำนักงาน']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 2 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 2 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 2 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_1'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 2 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 2 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + + await page.waitForTimeout(2000); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลทะเบียนนิติบุคคล', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 3 + await page.click('id=select-field_2'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_2'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ทะเบียนนิติบุคคล']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 3 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 3 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 3 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_2'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 3 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 3 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + + await page.waitForTimeout(2000); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลเบอร์โทรสำนักงาน', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 4 + await page.click('id=select-field_3'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_3'); + const column1Cells = page.locator( + "//th[normalize-space(text())='เบอร์โทรสำนักงาน']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 4 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 4 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 4 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_3'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 4 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 4 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + + await page.waitForTimeout(2000); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลติดต่อ', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 5 + await page.click('id=select-field_4'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_4'); + const column1Cells = page.locator("//th[normalize-space(text())='ติดต่อ']"); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 5 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 5 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 5 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_4'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 5 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 5 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + + await page.waitForTimeout(2000); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลที่อยู่', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 6 + await page.click('id=select-field_5'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_5'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ที่อยู่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 6 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 6 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 6 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_5'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 6 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 6 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + + await page.waitForTimeout(2000); +}); diff --git a/tests/01-Admin-BranchManagement/JWS_BM_008_CloseStatusBranchandSub.spec.ts b/tests/01-Admin-BranchManagement/JWS_BM_008_CloseStatusBranchandSub.spec.ts deleted file mode 100644 index 887720fa..00000000 --- a/tests/01-Admin-BranchManagement/JWS_BM_008_CloseStatusBranchandSub.spec.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { test, expect, Page } from '@playwright/test'; -import { strictEqual } from 'assert'; - -let page: Page; - -test.beforeAll(async ({ browser }) => { - page = await browser.newPage(); -}); - -test.afterAll(async () => { - if (page !== undefined) { - await page.close(); - } -}); - -test('Login', async () => { - // Login - await page.goto('http://192.168.1.90:20001/'); - await expect(page).toHaveTitle(/^Sign in to /); - await page.fill("input[name='username']", 'admin'); - await page.fill("input[name='password']", '1234'); - await page.click('id=kc-login'); - await page.waitForTimeout(2000); - // await page.click('id=acceptBtn'); -}); - -test('Close Status Branch Headquater', async () => { - await page.click('id=menu-icon-branch-management'); - await page.click('id=view-detail-btn-สาทร'); - await page.click( - "//div[contains(@class,'q-toggle__inner relative-position')]", - ); - await page.waitForTimeout(2000); - await page.keyboard.press('Escape'); -}); - -test('Open Status Branch Headquater', async () => { - await page.click('id=view-detail-btn-สาทร'); - await page.click( - "//div[contains(@class,'q-toggle__inner relative-position')]", - ); - await page.waitForTimeout(2000); - await page.keyboard.press('Escape'); -}); - -test('Close Status Sub-Branch Headquater', async () => { - await page.click( - "(//div[contains(@class,'q-tree__node-header relative-position')])[3]", - ); - await page.click('id=branch-card-สาทร'); - await page.click('id=view-detail-btn-สีลม3'); - await page.click( - "//div[contains(@class,'q-toggle__inner relative-position')]", - ); - await page.waitForTimeout(2000); - await page.keyboard.press('Escape'); - await page.waitForTimeout(4000); -}); diff --git a/tests/01-Admin-BranchManagement/JWS_BM_008_ViewDetail.spec.ts b/tests/01-Admin-BranchManagement/JWS_BM_008_ViewDetail.spec.ts new file mode 100644 index 00000000..5ac5db74 --- /dev/null +++ b/tests/01-Admin-BranchManagement/JWS_BM_008_ViewDetail.spec.ts @@ -0,0 +1,91 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('View Detail Headquter Branch', async () => { + try { + await page.click('id=menu-icon-branch-management'); + await page.click('id=btn-kebab-action-บริษัท โคโม่ จำกัด'); + await page.click('id=btn-kebab-view-detail-บริษัท โคโม่ จำกัด'); + + const detailTitle = page.locator( + "//span[text()='บริษัท โคโม่ จำกัด ']/following-sibling::span", + ); + + await expect(detailTitle).toHaveText('CMO00000'); // เลขรหัสสำนักงานใหญ่ + + console.log('ตรวจสอบข้อมูลถูกต้อง'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ', error); + throw error; + } + + await page.waitForTimeout(4000); + await page.click('id=btn-info-close'); +}); + +test('View Detail Sub Branch', async () => { + try { + await page.click("(//div[@id='tree-enter-บริษัท โคโม่ จำกัด']//div)[1]"); + await page.click('id=btn-kebab-action-สีลม1'); + await page.click('id=btn-kebab-view-detail-สีลม1'); + + const detailTitle = page.locator("//span[text()='สีลม1 ']"); + + await detailTitle.waitFor({ state: 'visible' }); + + await expect(detailTitle).toHaveText('สีลม1'); // เลขรหัสสำนักงานใหญ่ + + console.log('ตรวจสอบข้อมูลถูกต้อง'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ', error); + throw error; + } + + await page.waitForTimeout(4000); + await page.click('id=btn-info-close'); +}); + +test('View Detail Service Point', async () => { + try { + await page.click("//div[@id='tree-enter-บริษัท คาโมมายด์ จำกัด']/div[1]"); + await page.click('id=btn-kebab-action-บางรัก1'); + await page.click('id=btn-kebab-view-detail-บางรัก1'); + + const detailTitle = page.locator("//span[text()='บางรัก1 ']"); + + await detailTitle.waitFor({ state: 'visible' }); + + await expect(detailTitle).toHaveText('บางรัก1'); // เลขรหัสสำนักงานใหญ่ + + console.log('ตรวจสอบข้อมูลถูกต้อง'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ', error); + throw error; + } + + await page.waitForTimeout(4000); + await page.click('id=btn-info-close'); +}); diff --git a/tests/01-Admin-BranchManagement/JWS_BM_009_EditBranch.spec.ts b/tests/01-Admin-BranchManagement/JWS_BM_009_EditBranch.spec.ts new file mode 100644 index 00000000..7c14e2af --- /dev/null +++ b/tests/01-Admin-BranchManagement/JWS_BM_009_EditBranch.spec.ts @@ -0,0 +1,129 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; +import exp from 'constants'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Edit Headquter Branch', async () => { + try { + // แก้ไขสำนักงานใหญ่ + await page.click('id=menu-icon-branch-management'); + await page.click('id=btn-kebab-action-บริษัท โคโม่ จำกัด'); + await page.click('id=btn-kebab-edit-บริษัท โคโม่ จำกัด'); + await page.fill('id=input-name', 'บริษัท โคโมโดะ จำกัด'); + await page.fill('id=input-name-en', 'COMODO'); + await page.click('id=btn-info-basic-save'); + + //ตรวจสอบรายละเอียดการแก้ไข + await page.click('id=btn-kebab-action-บริษัท โคโมโดะ จำกัด'); + await page.click('id=btn-kebab-view-detail-บริษัท โคโมโดะ จำกัด'); + + //ตรวจสอบว่าได้ทำการแก้ไขถูกต้องหรือไม่ + const detailEditName = await page.inputValue( + "//input[@value='บริษัท โคโมโดะ จำกัด']", + ); + const detailEditNameEn = await page.inputValue( + "//input[@aria-label='ชื่อสำนักงานใหญ่ (EN)']", + ); + + await expect(detailEditName).toBe('บริษัท โคโมโดะ จำกัด'); + await expect(detailEditNameEn).toBe('COMODO'); + + console.log('ตรวจสอบการแก้ไขข้อมูลสำนักงานใหญ่ถูกต้อง'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ', error); + throw error; + } + + await page.waitForTimeout(4000); + await page.click('id=btn-info-close'); +}); + +test('Edit Sub Branch', async () => { + try { + // แก้ไขสำนักงานใหญ่ + await page.click("//div[@id='tree-enter-บริษัท โคโมโดะ จำกัด']/div[1]"); + await page.waitForSelector('id=btn-kebab-action-สีลม1', { + state: 'visible', + }); + await page.click('id=btn-kebab-action-สีลม1'); + await page.waitForTimeout(1000); + await page.click('id=btn-kebab-edit-สีลม1'); + await page.fill('id=input-name', 'สินสาทร'); + await page.fill('id=input-name-en', 'Sinsathorn'); + await page.click('id=btn-info-basic-save'); + + //ตรวจสอบรายละเอียดการแก้ไข + await page.click('id=btn-kebab-action-สินสาทร'); + await page.click('id=btn-kebab-view-detail-สินสาทร'); + + //ตรวจสอบว่าได้ทำการแก้ไขถูกต้องหรือไม่ + const detailEditName = await page.inputValue("//input[@value='สินสาทร']"); + const detailEditNameEn = await page.inputValue( + "//input[@value='Sinsathorn']", + ); + + await expect(detailEditName).toBe('สินสาทร'); + await expect(detailEditNameEn).toBe('Sinsathorn'); + + console.log('ตรวจสอบการแก้ไขข้อมูลสาขาถูกต้อง'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ', error); + throw error; + } + + await page.waitForTimeout(4000); + await page.click('id=btn-info-close'); +}); + +test('Edit Visual Branch', async () => { + try { + // แก้ไขสำนักงานใหญ่ + await page.click("//div[@id='tree-enter-บริษัท คาโมมายด์ จำกัด']/div[1]"); + await page.click('id=btn-kebab-action-บางรัก1'); + await page.click('id=btn-kebab-edit-บางรัก1'); + await page.fill('id=input-name', 'บางจาก'); + await page.fill('id=input-name-en', 'Bangjak'); + await page.click('id=btn-info-basic-save'); + + //ตรวจสอบรายละเอียดการแก้ไข + await page.click('id=btn-kebab-action-บางจาก'); + await page.click('id=btn-kebab-view-detail-บางจาก'); + + //ตรวจสอบว่าได้ทำการแก้ไขถูกต้องหรือไม่ + const detailEditName = await page.inputValue("//input[@value='บางจาก']"); + const detailEditNameEn = await page.inputValue("//input[@value='Bangjak']"); + + await expect(detailEditName).toBe('บางจาก'); + await expect(detailEditNameEn).toBe('Bangjak'); + + console.log('ตรวจสอบการแก้ไขข้อมูลสาขาเสมือนถูกต้อง'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ', error); + throw error; + } + + await page.waitForTimeout(4000); + await page.click('id=btn-info-close'); +}); diff --git a/tests/01-Admin-BranchManagement/JWS_BM_010_StatusBranchandSubType.spec.ts b/tests/01-Admin-BranchManagement/JWS_BM_010_StatusBranchandSubType.spec.ts new file mode 100644 index 00000000..efcb464d --- /dev/null +++ b/tests/01-Admin-BranchManagement/JWS_BM_010_StatusBranchandSubType.spec.ts @@ -0,0 +1,229 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('ตรวจสอบการแสดงผลสถานะการใช้งาน เปิด/ปิด สำนักงานใหญ่', async () => { + try { + // คลิกเมนูเพื่อจัดการสาขา + await page.click('id=menu-icon-branch-management'); + + // แสดงสถานะที่ใช้งาน + // คลิกเพื่อเปิด dropdown + await page.click('id=field-select-status'); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อแสดงสถานะกำลังใช้งานอยู่ + await page.click('id=field-select-status_1'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่ามีแต่สถานะใช้งานหรือไม่ + const statusActive = await page.isVisible('id=field-select-status_1'); + + console.log('มีเพียงสถานะการใช้งานเท่านั้น', statusActive); // เช็ค + + expect(statusActive).toBe(false); + + console.log('ตรวจสอบสถานะการใช้งานมีแต่สถานะกำลังใช้งานเท่านั้น'); + + // แสดงสถานะที่ไม่ใช้งาน + // คลิกเพื่อเปิด dropdown + await page.keyboard.press('Escape'); + await page.click('id=field-select-status'); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อแสดงสถานะกำลังไม่ใช้งาน + await page.click('id=field-select-status_2'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่ามีแต่สถานะไม่ใช้งานหรือไม่ + const statusInActive = await page.isVisible('id=field-select-status_1'); + + console.log('มีเพียงสถานะการใช้งานเท่านั้น', statusInActive); // เช็ค + + expect(statusActive).toBe(false); + + console.log('ตรวจสอบสถานะการใช้งานมีแต่สถานะที่ไม่ใช้งาน'); + + // แสดงสถานะทั้งหมด + // คลิกเพื่อเปิด dropdown + await page.keyboard.press('Escape'); + await page.click('id=field-select-status'); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อแสดงสถานะทั้งหมด + await page.click('id=field-select-status_0'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าแสดงทุกสถานะหรือไม่ + const statusAll = await page.isVisible('id=field-select-status_1'); + + console.log('สถานะทั้งหมด', statusAll); // เช็ค + + expect(statusActive).toBe(false); + + console.log('ตรวจสอบสถานะทั้งหมด'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + + await page.waitForTimeout(2000); +}); + +// test('ตรวจสอบการแสดงผลสถานะการใช้งาน เปิด/ปิด สาขา', async () => { +// try { +// // คลิกเข้าสู่สาขา +// await page.click("//div[@id='tree-enter-บริษัท โคโมโดะ จำกัด']/div[1]"); + +// // แสดงสถานะที่ใช้งาน +// // คลิกเพื่อเปิด dropdown +// await page.click('id=field-select-status'); +// await page.waitForTimeout(1000); // รอให้ dropdown เปิด + +// // คลิกเพื่อแสดงสถานะกำลังใช้งานอยู่ +// await page.click('id=field-select-status_1'); +// await page.waitForTimeout(1000); // รอให้ UI อัปเดต + +// // ตรวจสอบว่ามีแต่สถานะใช้งานหรือไม่ +// const statusActive = await page.isVisible('id=field-select-status_1'); + +// console.log('มีเพียงสถานะการใช้งานเท่านั้น', statusActive); // เช็ค + +// expect(statusActive).toBe(false); + +// console.log('ตรวจสอบสถานะการใช้งานมีแต่สถานะกำลังใช้งานเท่านั้น'); + +// // แสดงสถานะที่ไม่ใช้งาน +// // คลิกเพื่อเปิด dropdown +// await page.keyboard.press('Escape'); +// await page.click('id=field-select-status'); +// await page.waitForTimeout(1000); // รอให้ dropdown เปิด + +// // คลิกเพื่อแสดงสถานะกำลังไม่ใช้งาน +// await page.click('id=field-select-status_2'); +// await page.waitForTimeout(1000); // รอให้ UI อัปเดต + +// // ตรวจสอบว่ามีแต่สถานะไม่ใช้งานหรือไม่ +// const statusInActive = await page.isVisible('id=field-select-status_1'); + +// console.log('มีเพียงสถานะการใช้งานเท่านั้น', statusInActive); // เช็ค + +// expect(statusActive).toBe(false); + +// console.log('ตรวจสอบสถานะการใช้งานมีแต่สถานะที่ไม่ใช้งาน'); + +// // แสดงสถานะทั้งหมด +// // คลิกเพื่อเปิด dropdown +// await page.keyboard.press('Escape'); +// await page.click('id=field-select-status'); +// await page.waitForTimeout(1000); // รอให้ dropdown เปิด + +// // คลิกเพื่อแสดงสถานะทั้งหมด +// await page.click('id=field-select-status_0'); +// await page.waitForTimeout(1000); // รอให้ UI อัปเดต + +// // ตรวจสอบว่าแสดงทุกสถานะหรือไม่ +// const statusAll = await page.isVisible('id=field-select-status_1'); + +// console.log('สถานะทั้งหมด', statusAll); // เช็ค + +// expect(statusActive).toBe(false); + +// console.log('ตรวจสอบสถานะทั้งหมด'); +// } catch (error) { +// console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); +// throw error; +// } + +// await page.waitForTimeout(2000); +// }); + +// test('ตรวจสอบการแสดงผลสถานะการใช้งาน เปิด/ปิด จุดรับบริการ', async () => { +// try { +// // คลิกเข้าสู่สาขาเสมือน +// await page.click("//div[@id='tree-enter-บริษัท คาโมมายด์ จำกัด']/div[1]"); + +// // แสดงสถานะที่ใช้งาน +// // คลิกเพื่อเปิด dropdown +// await page.click('id=field-select-status'); +// await page.waitForTimeout(1000); // รอให้ dropdown เปิด + +// // คลิกเพื่อแสดงสถานะกำลังใช้งานอยู่ +// await page.click('id=field-select-status_1'); +// await page.waitForTimeout(1000); // รอให้ UI อัปเดต + +// // ตรวจสอบว่ามีแต่สถานะใช้งานหรือไม่ +// const statusActive = await page.isVisible('id=field-select-status_1'); + +// console.log('มีเพียงสถานะการใช้งานเท่านั้น', statusActive); // เช็ค + +// expect(statusActive).toBe(false); + +// console.log('ตรวจสอบสถานะการใช้งานมีแต่สถานะกำลังใช้งานเท่านั้น'); + +// // แสดงสถานะที่ไม่ใช้งาน +// // คลิกเพื่อเปิด dropdown +// await page.keyboard.press('Escape'); +// await page.click('id=field-select-status'); +// await page.waitForTimeout(1000); // รอให้ dropdown เปิด + +// // คลิกเพื่อแสดงสถานะกำลังไม่ใช้งาน +// await page.click('id=field-select-status_2'); +// await page.waitForTimeout(1000); // รอให้ UI อัปเดต + +// // ตรวจสอบว่ามีแต่สถานะไม่ใช้งานหรือไม่ +// const statusInActive = await page.isVisible('id=field-select-status_1'); + +// console.log('มีเพียงสถานะการใช้งานเท่านั้น', statusInActive); // เช็ค + +// expect(statusActive).toBe(false); + +// console.log('ตรวจสอบสถานะการใช้งานมีแต่สถานะที่ไม่ใช้งาน'); + +// // แสดงสถานะทั้งหมด +// // คลิกเพื่อเปิด dropdown +// await page.keyboard.press('Escape'); +// await page.click('id=field-select-status'); +// await page.waitForTimeout(1000); // รอให้ dropdown เปิด + +// // คลิกเพื่อแสดงสถานะทั้งหมด +// await page.click('id=field-select-status_0'); +// await page.waitForTimeout(1000); // รอให้ UI อัปเดต + +// // ตรวจสอบว่าแสดงทุกสถานะหรือไม่ +// const statusAll = await page.isVisible('id=field-select-status_1'); + +// console.log('สถานะทั้งหมด', statusAll); // เช็ค + +// expect(statusActive).toBe(false); + +// console.log('ตรวจสอบสถานะทั้งหมด'); +// } catch (error) { +// console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); +// throw error; +// } + +// await page.waitForTimeout(2000); +// }); diff --git a/tests/01-Admin-BranchManagement/JWS_BM_011_SearchBranchmanagement.spec.ts b/tests/01-Admin-BranchManagement/JWS_BM_011_SearchBranchmanagement.spec.ts new file mode 100644 index 00000000..4a5be902 --- /dev/null +++ b/tests/01-Admin-BranchManagement/JWS_BM_011_SearchBranchmanagement.spec.ts @@ -0,0 +1,85 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; +import { Console, error, log } from 'console'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Search Data Branch Management', async () => { + await page.click('id=menu-icon-branch-management'); + + try { + // กำหนดคำที่จะค้นหา + const searchDatas = [ + 'โคโมโดะ', + 'คาโมมายด์', + 'CM', + 'CMO', + '00000', + 'บางจาก', + 'บางรัก', + 'สีลม1', + ]; + + for (const searchData of searchDatas) { + // พิมพ์คำที่ต้องการค้นหา + await page.fill('id=input-search', searchData); // ดึงคำมาจาก searchDatas + await page.waitForTimeout(2000); + + // ดึงผลลัพฑ์การค้นหาทั้งหมด + const searchResults = page.locator("//table[@class='q-table']//tbody[1]"); + const resultCount = await searchResults.count(); + + // ถ้าไม่มีผลลัพธ์ให้ข้ามคำถัดไป + if (resultCount === 0) { + console.error(`ไม่พบการค้นหา: '${searchData}', ข้ามไปคำถัดไป`); + continue; // ข้ามคำค้นหาคำถัดไป + } + + // ดึงข้อความทั้งหมดของผลลัพธ์การค้นหา + const searchResultTexts = await searchResults.allTextContents(); + console.log(`ผลลัพธ์ของการค้นหา '${searchData}'`, searchDatas); + + // ตรวจสอบว่าผลลัพธ์ทั้งหมดมีคำที่ค้นหาหรือไม่ + const allResultContainSearchData = searchResultTexts.every((result) => + result.includes(searchData), + ); + + // ถ้าไม่พบคำค้นหา ให้แค่แจ้งเตือนและข้ามไปคำถัดไป + if (!allResultContainSearchData) { + console.error( + `\x1b[31mผลลัพธ์บางรายการไม่ตรงกับคำค้นหา: '${searchData}', ข้ามไปคำถัดไป\x1b[0m`, + ); + continue; // ข้ามไปคำค้นหาถัดไป + } + + expect(allResultContainSearchData).toBe(true); + + console.log(`การค้นหา '${searchData}' และการแสดงผลสำเร็จ`); + } + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบการค้นหาหลายคำค้นหา', error); + throw error; + } + await page.waitForTimeout(2000); +}); diff --git a/tests/01-Admin-BranchManagement/JWS_BM_012_CloseStatusBranch.spec.ts b/tests/01-Admin-BranchManagement/JWS_BM_012_CloseStatusBranch.spec.ts new file mode 100644 index 00000000..dc671956 --- /dev/null +++ b/tests/01-Admin-BranchManagement/JWS_BM_012_CloseStatusBranch.spec.ts @@ -0,0 +1,99 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; +import { Console, error, log } from 'console'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('ปิดการใช้งานสำนักงานใหญ่', async () => { + try { + await page.click('id=menu-icon-branch-management'); + await page.click('id=btn-kebab-action-บริษัท คาโมมายด์ จำกัด'); + + await page.click('id=btn-kebab-status-บริษัท คาโมมายด์ จำกัด', { + force: true, + }); + await page.click('id=btn-ok-dialog'); + console.log('เปลี่ยนสถานะสำเร็จ'); + await page.reload(); + + // รอ Update + await page.waitForTimeout(2000); + console.log('สถานะถูกเปลี่ยนแล้ว'); + + // ตรวจสอบสีของแถวหลังจากทำการเปลี่ยนสถานะ + const rowLocator = page.locator( + "//td[contains(.,'บริษัท คาโมมายด์ จำกัดCMM00000')]", + ); + const backgroundColor = await rowLocator.evaluate( + (el) => window.getComputedStyle(el).backgroundColor, + ); + + // กำหนดสีหลัเปลี่ยนสถานะการใช้งาน + const expectedColor = 'rgb(249, 250, 252)'; + + // ตรวจสอบสีที่เปลี่ยนไป + expect(backgroundColor.trim()).toBe(expectedColor); + console.log('สีของแถวถูกเปลี่ยนเป็นสีเทาอ่อน'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ'); + throw error; + } + await page.waitForTimeout(2000); +}); + +test('เปิดการใช้งานสำนักงานใหญ่', async () => { + try { + await page.click('id=btn-kebab-action-บริษัท คาโมมายด์ จำกัด'); + + await page.click('id=btn-kebab-status-บริษัท คาโมมายด์ จำกัด', { + force: true, + }); + await page.click('id=btn-ok-dialog'); + console.log('เปลี่ยนสถานะสำเร็จ'); + await page.reload(); + + // รอ Update + await page.waitForTimeout(2000); + console.log('สถานะถูกเปลี่ยนแล้ว'); + + // ตรวจสอบสีของแถวหลังจากทำการเปลี่ยนสถานะ + const rowLocator = page.locator( + "//td[contains(.,'บริษัท คาโมมายด์ จำกัดCMM00000')]", + ); + const backgroundColor = await rowLocator.evaluate( + (el) => window.getComputedStyle(el).backgroundColor, + ); + + // กำหนดสีหลัเปลี่ยนสถานะการใช้งาน + const expectedColor = 'rgba(0, 0, 0, 0)'; + + // ตรวจสอบสีที่เปลี่ยนไป + expect(backgroundColor.trim()).toBe(expectedColor); + console.log('สีของแถวถูกเปลี่ยนเป็นของสถานะการใช้งาน'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ'); + throw error; + } + await page.waitForTimeout(2000); +}); diff --git a/tests/01-Admin-BranchManagement/JWS_BM_013_DeleteBranch.spec.ts b/tests/01-Admin-BranchManagement/JWS_BM_013_DeleteBranch.spec.ts new file mode 100644 index 00000000..2ceaab3f --- /dev/null +++ b/tests/01-Admin-BranchManagement/JWS_BM_013_DeleteBranch.spec.ts @@ -0,0 +1,217 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; +import { Console, error, log } from 'console'; +import exp from 'constants'; +import { it } from 'node:test'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('ทดสอบการลบจัดการสาขา', async () => { + await page.click('id=menu-icon-branch-management'); + + // จำลองการสร้างสำนักงานใหญ่ + + await page.click('id=hq-add-btn'); + await page.fill("(//input[@id='input-abbreviation'])[2]", 'TES'); + await page.fill("(//input[@id='input-tax-no'])[2]", '1260846220284'); + await page.fill("(//input[@id='input-name'])[2]", 'บริษัท จำลอง จำกัด'); + await page.fill("(//input[@id='input-name-en'])[2]", 'JOMLONG'); + await page.fill("(//input[@id='input-email'])[2]", 'JOM@support.com'); + await page.fill("(//input[@id='input-telephone-no'])[2]", '022010100'); + await page.fill("(//input[@id='input-contact-name'])[2]", 'คุณอาท'); + await page.fill("(//input[@id='input-contact'])[2]", '0866224228'); + await page.fill("(//input[@id='input-line-id'])[2]", 'como20'); + await page.fill("(//input[@id='default-input-address'])[2]", '40/04'); + await page.click("(//input[@id='default-select-province'])[2]"); + await page.click("//div[@role='option']"); + await page.click("(//input[@id='default-select-district'])[2]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.click("(//input[@id='default-select-sub-district'])[2]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.fill("(//input[@id='default-input-address-en'])[2]", '40/04'); + await page.click("(//input[@id='select-bankbook'])[3]"); + await page.click('id=select-bankbook_4'); + await page.fill("(//input[@aria-label='เลขบัญชี'])[2]", '2022822624262'); + await page.fill("(//input[@aria-label='สาขาธนาคาร'])[2]", 'ลำพูน'); + await page.fill("(//input[@aria-label='ชื่อบัญชี'])[2]", 'Pongpon Kuntana'); + await page.click("(//input[@aria-label='ประเภทบัญชี'])[2]"); + await page.waitForTimeout(2000); + await page.click('id=select-bankbook_0'); + await page.click('id=btn-form-submit'); + + await page.waitForSelector('id=btn-ok-dialog'); + await page.click('id=btn-ok-dialog'); + + // จำลองการสร้างสาขา + + await page.click('id=create-sub-branch-btn-บริษัท จำลอง จำกัด'); + await page.click("(//button[@type='submit'])[1]"); + + await page.fill("(//input[@id='input-tax-no'])[2]", '1260846220281'); + await page.fill("(//input[@id='input-name'])[3]", 'สาขาจำลอง'); + await page.fill("(//input[@id='input-name-en'])[2]", 'SAKAJOMLONG'); + await page.fill( + "(//input[@aria-label='เลขที่ใบอนุญาต'])[2]", + '1228222822822', + ); + await page.fill("(//input[@id='input-email'])[2]", 'test@support.com'); + await page.fill("(//input[@id='input-telephone-no'])[2]", '022222002'); + await page.fill("(//input[@id='input-contact-name'])[2]", 'คุณอาท'); + await page.fill("(//input[@id='input-contact'])[2]", '0822262228'); + await page.fill("(//input[@id='input-line-id'])[2]", 'company'); + + await page.fill("(//input[@id='default-input-address-no'])[2]", '20/02'); + await page.click("(//input[@id='default-select-province'])[2]"); + await page.click("//div[@role='option']"); + await page.click("(//input[@id='default-select-district'])[2]"); + await page.waitForTimeout(400); + await page.click("//div[@role='option']"); + await page.click("(//input[@id='default-select-sub-district'])[2]"); + await page.waitForTimeout(400); + await page.click("//div[@role='option']"); + await page.fill("(//input[@id='default-input-address-en'])[2]", '20/02'); + + await page.click("(//input[@id='select-bankbook'])[3]"); + await page.click('id=select-bankbook_1'); + await page.fill("(//input[@aria-label='เลขบัญชี'])[2]", '2282020021'); + await page.fill("(//input[@aria-label='สาขาธนาคาร'])[2]", 'เชียงใหม่'); + await page.fill("(//input[@aria-label='ชื่อบัญชี'])[2]", 'Pongpon Kuntana'); + await page.click("(//input[@aria-label='ประเภทบัญชี'])[2]"); + await page.waitForTimeout(2000); + await page.click('id=select-bankbook_0'); + + await page.click('id=btn-form-submit'); + + // จำลองการสร้างสาขาเสมือน + + await page.click('id=create-sub-branch-btn-บริษัท จำลอง จำกัด'); + await page.click("(//button[@type='submit'])[2]"); + + await page.fill("(//input[@id='input-tax-no'])[2]", '2022826282642'); + await page.fill("(//input[@id='input-name'])[2]", 'สาขาเสมือน'); + await page.fill("(//input[@id='input-name-en'])[2]", 'VISUALBRANCH'); + await page.fill("(//input[@id='input-email'])[2]", 'visual@local.co.th'); + await page.fill("(//input[@id='input-telephone-no'])[2]", '022222002'); + await page.fill("(//input[@id='input-contact-name'])[2]", 'คุณอุล'); + await page.fill("(//input[@id='input-contact'])[2]", '0822622862'); + await page.fill("(//input[@id='input-line-id'])[2]", 'cmmsupport'); + + await page.fill("(//input[@id='default-input-address'])[2]", '40/04'); + await page.click("(//input[@id='default-select-province'])[2]"); + await page.click("//div[@role='option']"); + await page.click("(//input[@id='default-select-district'])[2]"); + await page.waitForTimeout(400); + await page.click("//div[@role='option']"); + await page.click("(//input[@id='default-select-sub-district'])[2]"); + await page.waitForTimeout(400); + await page.click("//div[@role='option']"); + await page.fill("(//input[@id='default-input-address-en'])[2]", '40/04'); + + await page.click("(//input[@id='select-bankbook'])[3]"); + await page.click('id=select-bankbook_2'); + await page.fill("(//input[@aria-label='เลขบัญชี'])[2]", '2822642201'); + await page.fill("(//input[@aria-label='สาขาธนาคาร'])[2]", 'ลำพูน'); + await page.fill("(//input[@aria-label='ชื่อบัญชี'])[2]", 'Pongpon Kuntana'); + await page.click("(//input[@aria-label='ประเภทบัญชี'])[2]"); + await page.waitForTimeout(2000); + await page.click('id=select-bankbook_0'); + + await page.click('id=btn-form-submit'); + + // ลบสาขาและตรวจสอบการลบสาขา + try { + await page.click('id=btn-kebab-action-สาขาจำลอง'); + await page.click('id=btn-kebab-delete-สาขาจำลอง'); + + // ยืนยันการลบ + await page.click('id=btn-ok-dialog'); + await page.waitForTimeout(1000); + + // ตรวจสอบการลบสาขา + const itemLocator = page.locator( + "//tr[contains(.,'1 สาขาจำลองTES0000112608462202810822262228คุณอาท20/02')]", + ); + + // ตรวจสอบว่าถูกลบออกจากระบบหรือไม่ + await expect(itemLocator).toBeHidden(); + + console.log('ตรวจสอบข้อมูลการลบสาขาสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการลบสาขา', error); + throw error; + } + + // ลบสาขาเสมือนและตรวจสอบการลบสาขาเสมือน + + try { + await page.click('id=btn-kebab-action-สาขาเสมือน'); + await page.click('id=btn-kebab-delete-สาขาเสมือน'); + + // ยืนยันการลบ + await page.click('id=btn-ok-dialog'); + await page.waitForTimeout(1000); + + // ตรวจสอบการลบสาขาเสมือน + const itemLocator = page.locator( + "//tr[contains(.,'2 สาขาเสมือนTES0000220228262826420822622862คุณอุล40/04')]", + ); + + // ตรวจสอบว่าถูกลบออกจากระบบหรือไม่ + await expect(itemLocator).toBeHidden(); + + console.log('ตรวจสอบข้อมูลการลบสาขาเสมือนสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการลบสาขาเสมือน', error); + throw error; + } + + // // ลบสำนักงานใหญ่และตรวจสอบการลบสำนักงานใหญ่ + + // await page.click("//div[@id='tree-enter-บริษัท จำลอง จำกัด']/div[1]"); + // try { + // await page.click('id=btn-kebab-action-บริษัท จำลอง จำกัด'); + // await page.click('id=btn-kebab-delete-บริษัท จำลอง จำกัด'); + + // // ยืนยันการลบ + // await page.click('id=btn-ok-dialog'); + // await page.waitForTimeout(1000); + + // // ตรวจสอบการลบสำนักงานใหญ่ + // const itemLocator = page.locator( + // "//tr[contains(.,'9 บริษัท จำลอง จำกัดTES0000012608462202840866224228คุณอาท40/04')]", + // ); + + // // ตรวจสอบว่าถูกลบออกจากระบบหรือไม่ + // await expect(itemLocator).toBeHidden(); + + // console.log('ตรวจสอบข้อมูลการลบสำนักงานใหญ่สำเร็จ'); + // } catch (error) { + // console.error('เกิดข้อผิดพลาดในการลบสำนักงานใหญ่', error); + // throw error; + // } + + await page.waitForTimeout(2000); +}); diff --git a/tests/02-Admin-PersonnelManagement/JWS_PM_001_CreatePersonnel.spec.ts b/tests/02-Admin-PersonnelManagement/JWS_PM_001_CreatePersonnel.spec.ts index 152ab264..8ba381c2 100644 --- a/tests/02-Admin-PersonnelManagement/JWS_PM_001_CreatePersonnel.spec.ts +++ b/tests/02-Admin-PersonnelManagement/JWS_PM_001_CreatePersonnel.spec.ts @@ -1,5 +1,6 @@ import { test, expect, Page } from '@playwright/test'; import { strictEqual } from 'assert'; +import exp from 'constants'; let page: Page; @@ -26,309 +27,767 @@ test('Login', async () => { test('Create Personnel พนักงาน ชาย', async () => { await page.click('id=menu-icon-personnel-management'); - for (let i = 1; i < 5; i++) { - await page.click('id=btn-add'); - await page.click('id=btn-add-personne'); - await page.fill('id=input-username', `user${i + 1}`); - // await page.click('id=select-user-type'); - // await page.click("//span[text()='พนักงาน']"); - await page.click('id=select-user-role'); - await page.click("//span[text()='System']"); - await page.click("//div[@role='option']"); - await page.fill('id=input-first-name', `ทดสอบ${i + 1}`); - await page.fill('id=input-last-name', `ทดสอบ${i + 1}`); - await page.fill('id=input-first-name-en', `Firstname${i + 1}`); - await page.fill('id=input-last-name-en', `Lastname${i + 1}`); - await page.click('id=select-gender'); - await page.click("//span[text()='ชาย']"); - await page.click('id=input-birth-date'); - await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); - await page.click("//div[text()='2021']"); - await page.click("//div[text()='10']"); - await page.fill('id=input-address', `20/0${i + 1}`); - await page.click('id=select-province'); - await page.click("//span[text()='เชียงใหม่']"); - await page.click('id=select-district'); - await page.click("//span[text()='เมือง']"); - await page.click('id=select-sub-district'); - await page.click("//span[text()='ช้างเผือก']"); - await page.fill('id=input-address-en', `20/0${i + 1}`); - await page.fill('id=input-regis-no', `282228222242${i + 1}`); - await page.click('id=input-start-date'); - await page.click(`//div[text()='1${i + 1}']`); - await page.click('id=input-retire-date'); - await page.click(`//div[text()='2${i + 1}']`); - await page.click('id=submitBtn'); - await page.click('id=btn-ok-dialog'); - } - await page.waitForTimeout(4000); + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + + // กรอกข้อมูลพื้นฐานของบุคคลากร + await page.click("//i[@aria-hidden='false']"); + await page.waitForSelector('id=select-hq-id', { + state: 'visible', + }); + await page.click('id=select-hq-id'); + await page.click("//span[normalize-space(text())='CMO00000']"); + + await page.waitForSelector('id=select-br-id', { state: 'visible' }); + await page.click('id=select-br-id'); + await page.click('id=select-br-id_4'); + await page.fill('id=input-username', 'employeem'); + await page.click('id=select-user-type'); + await page.click('id=select-user-type_0'); + await page.click('id=select-user-role'); + await page.click('id=select-user-role_2'); + // await page.click("//div[@role='option']"); + + // กรอกชื่อข้อมูลพื้นฐาน + await page.fill('id=input-citizen-id', '1282262422820'); + await page.click("//label[@for='form-dialog-personnel-select-prefix-name']"); + await page.click('id=form-dialog-personnel-select-prefix-name_0'); + await page.fill('id=form-dialog-personnel-input-first-name', 'ธรรมรงด์'); + await page.fill('id=form-dialog-personnel-input-last-name', 'ดำรงธรรม'); + await page.fill('id=form-dialog-personnel-input-first-name-en', 'Thamrong'); + await page.fill('id=form-dialog-personnel-input-last-name-en', 'Dumrongtum'); + await page.fill('id=form-dialog-personnel-input-telephone', '08422622282'); + await page.fill('id=form-dialog-personnel-input-email', 'employeem@mail.com'); + + // เลือกเพศ + await page.click('id=form-dialog-personnel-select-gender'); + await page.click("//span[text()='ชาย']"); + + // เลือกวันเกิด + await page.click('id=form-dialog-personnel-input-birth-date'); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='8']"); + + // วันออกบัตร วันที่หมออายุ + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-issue'])[1]", + ); + await page.click("//div[@id='2024-09-02']"); + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-expire'])[1]", + ); + await page.click("//div[@id='2024-09-17']/div[1]"); + + // กรอกที่อยู่ + await page.fill('id=drawer-info-personnel-input-address-no', '20/1'); + await page.click('id=drawer-info-personnel-select-province'); + await page.waitForSelector('id=drawer-info-personnel-select-province_6', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-province_6'); + await page.click('id=drawer-info-personnel-select-district'); + await page.waitForSelector('id=drawer-info-personnel-select-district_2', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-district_2'); + await page.click('id=drawer-info-personnel-select-sub-district'); + await page.waitForSelector('id=drawer-info-personnel-select-sub-district_1', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-sub-district_1'); + + // กรอกที่อยู่ภาษาอังกฤษ + await page.fill('id=drawer-info-personnel-input-address-en', '20/01'); + + // กรอกข้อมูลการทำงาน + await page.fill('id=input-regis-no', '2822282222421'); + await page.click('id=input-start-date'); + await page.click("//div[text()='11']"); + await page.click('id=input-retire-date'); + await page.click("//div[text()='21']"); + + // กดปุ่มเพื่อสร้างบุคคลากร + await page.click('id=btn-info-basic-save'); + await page.waitForTimeout(2000); + + // ดึงข้อมูลจาก Locator และนำ .textContent() เพื่อดึงมาแต่ข้อความจริง ๆ + await page.waitForSelector; + const displayNameLocator = page.locator( + "//div[normalize-space(text())='ธรรมรงด์ ดำรงธรรม']", + ); + + const displayName = (await displayNameLocator.textContent())?.trim() || ''; + + // ตรวจสอบข้อมูลที่ดึงออกมา + expect(displayName).toBe('ธรรมรงด์ ดำรงธรรม'); + console.log(displayName); + + console.log('ตรวจสอบการสร้างพนักงานชายถูกต้อง'); }); test('Create Personnel พนักงาน หญิง', async () => { - for (let i = 1; i < 10; i++) { - await page.click('id=btn-add'); - await page.click('id=btn-add-personne'); - await page.fill('id=input-username', `user${i + 5}`); - // await page.click('id=select-user-type'); - // await page.click("//span[text()='พนักงาน']"); - await page.click('id=select-user-role'); - await page.click("//span[text()='System']"); - await page.click("//div[@role='option']"); - await page.fill('id=input-first-name', `ทดสอบ${i + 5}`); - await page.fill('id=input-last-name', `ทดสอบ${i + 5}`); - await page.fill('id=input-first-name-en', `Firstname${i + 5}`); - await page.fill('id=input-last-name-en', `Lastname${i + 5}`); - await page.click('id=select-gender'); - await page.click("//span[text()='หญิง']"); - await page.click('id=input-birth-date'); - await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); - await page.click("//div[text()='2021']"); - await page.click("//div[text()='10']"); - await page.fill('id=input-address', `20/0${i + 5}`); - await page.click('id=select-province'); - await page.click("//span[text()='เชียงใหม่']"); - await page.click('id=select-district'); - await page.click("//span[text()='เมือง']"); - await page.click('id=select-sub-district'); - await page.click("//span[text()='ช้างเผือก']"); - await page.fill('id=input-address-en', `20/0${i + 5}`); - await page.fill('id=input-regis-no', `282228222242${i + 5}`); - await page.click('id=input-start-date'); - await page.click(`//div[text()='1${i + 5}']`); - await page.click('id=input-retire-date'); - await page.click(`//div[text()='2${i + 5}']`); - await page.click('id=submitBtn'); - await page.click('id=btn-ok-dialog'); - } - await page.waitForTimeout(4000); -}); + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); -test('Create Personnel พนักงานส่งเอกสาร ชาย', async () => { - for (let i = 1; i < 5; i++) { - await page.click('id=btn-add'); - await page.click('id=btn-add-personne'); - await page.fill('id=input-username', `user0${i + 1}`); - await page.click('id=select-user-type'); - await page.click("//span[text()='พนักงานส่งเอกสาร']"); - await page.click('id=select-user-role'); - await page.click("//span[text()='System']"); - await page.click("//div[@role='option']"); - await page.fill('id=input-first-name', `ทดสอบ${i + 1}`); - await page.fill('id=input-last-name', `ทดสอบ${i + 1}`); - await page.fill('id=input-first-name-en', `Firstname${i + 1}`); - await page.fill('id=input-last-name-en', `Lastname${i + 1}`); - await page.click('id=select-gender'); - await page.click("//span[text()='ชาย']"); - await page.click('id=input-birth-date'); - await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); - await page.click("//div[text()='2021']"); - await page.click("//div[text()='10']"); - await page.fill('id=input-address', `20/0${i + 1}`); - await page.click('id=select-province'); - await page.click("//span[text()='เชียงใหม่']"); - await page.click('id=select-district'); - await page.click("//span[text()='เมือง']"); - await page.click('id=select-sub-district'); - await page.click("//span[text()='ช้างเผือก']"); - await page.fill('id=input-address-en', `20/0${i + 1}`); - await page.fill('id=input-regis-no', `282228222222${i + 1}`); - await page.click('id=input-start-date'); - await page.click(`//div[text()='1${i + 1}']`); - await page.click('id=input-retire-date'); - await page.click(`//div[text()='2${i + 1}']`); - await page.click('id=submitBtn'); - await page.click('id=btn-ok-dialog'); - } - await page.waitForTimeout(4000); + // กรอกข้อมูลพื้นฐานของบุคคลากร + await page.click("//i[@aria-hidden='false']"); + await page.waitForSelector('id=select-hq-id', { + state: 'visible', + }); + await page.click('id=select-hq-id'); + await page.click("//span[normalize-space(text())='CMO00000']"); + + await page.waitForSelector('id=select-br-id', { state: 'visible' }); + await page.click('id=select-br-id'); + await page.click('id=select-br-id_4'); + await page.fill('id=input-username', 'employeew'); + await page.click('id=select-user-role'); + await page.click('id=select-user-role_6'); + // await page.click("//div[@role='option']"); + + // กรอกชื่อข้อมูลพื้นฐาน + await page.fill('id=input-citizen-id', '1282262422820'); + await page.click("//label[@for='form-dialog-personnel-select-prefix-name']"); + await page.click('id=form-dialog-personnel-select-prefix-name_0'); + await page.fill('id=form-dialog-personnel-input-first-name', 'อารยา'); + await page.fill('id=form-dialog-personnel-input-last-name', 'มาลา'); + await page.fill('id=form-dialog-personnel-input-first-name-en', 'Araya'); + await page.fill('id=form-dialog-personnel-input-last-name-en', 'Mala'); + await page.fill('id=form-dialog-personnel-input-telephone', '08422622282'); + await page.fill('id=form-dialog-personnel-input-email', 'employeew@mail.com'); + + // เลือกเพศ + await page.click('id=form-dialog-personnel-select-gender'); + await page.click("//span[text()='หญิง']"); + + // เลือกวันเกิด + await page.click('id=form-dialog-personnel-input-birth-date'); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='8']"); + + // วันออกบัตร วันที่หมออายุ + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-issue'])[1]", + ); + await page.click("//div[@id='2024-09-02']"); + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-expire'])[1]", + ); + await page.click("//div[@id='2024-09-16']/div[1]"); + + // กรอกที่อยู่ + await page.fill('id=drawer-info-personnel-input-address-no', '20/1'); + await page.click('id=drawer-info-personnel-select-province'); + await page.waitForSelector('id=drawer-info-personnel-select-province_6', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-province_6'); + await page.click('id=drawer-info-personnel-select-district'); + await page.waitForSelector('id=drawer-info-personnel-select-district_2', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-district_2'); + await page.click('id=drawer-info-personnel-select-sub-district'); + await page.waitForSelector('id=drawer-info-personnel-select-sub-district_1', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-sub-district_1'); + + // กรอกที่อยู่ภาษาอังกฤษ + await page.fill('id=drawer-info-personnel-input-address-en', '20/01'); + + // กรอกข้อมูลการทำงาน + await page.fill('id=input-regis-no', '2822282222421'); + await page.click('id=input-start-date'); + await page.click("//div[text()='11']"); + await page.click('id=input-retire-date'); + await page.click("//div[text()='21']"); + + // กดปุ่มเพื่อสร้างบุคคลากร + await page.click('id=btn-info-basic-save'); + await page.waitForTimeout(2000); + + // ดึงข้อมูลจาก Locator และนำ .textContent() เพื่อดึงมาแต่ข้อความจริง ๆ + const displayNameLocator = page.locator( + "//div[normalize-space(text())='อารยา มาลา']", + ); + const displayName = (await displayNameLocator.textContent())?.trim(); + + // ตรวจสอบข้อมูลที่ดึงออกมา + expect(displayName).toBe('อารยา มาลา'); + + console.log('ตรวจสอบการสร้างพนักงานหญิงถูกต้อง'); }); test('Create Personnel พนักงานส่งเอกสาร หญิง', async () => { - for (let i = 1; i < 10; i++) { - await page.click('id=btn-add'); - await page.click('id=btn-add-personne'); - await page.fill('id=input-username', `user0${i + 5}`); - await page.click('id=select-user-type'); - await page.click("//span[text()='พนักงานส่งเอกสาร']"); - await page.click('id=select-user-role'); - await page.click("//span[text()='System']"); - await page.click("//div[@role='option']"); - await page.fill('id=input-first-name', `ทดสอบ${i + 5}`); - await page.fill('id=input-last-name', `ทดสอบ${i + 5}`); - await page.fill('id=input-first-name-en', `Firstname${i + 5}`); - await page.fill('id=input-last-name-en', `Lastname${i + 5}`); - await page.click('id=select-gender'); - await page.click("//span[text()='หญิง']"); - await page.click('id=input-birth-date'); - await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); - await page.click("//div[text()='2021']"); - await page.click("//div[text()='10']"); - await page.fill('id=input-address', `20/0${i + 5}`); - await page.click('id=select-province'); - await page.click("//span[text()='เชียงใหม่']"); - await page.click('id=select-district'); - await page.click("//span[text()='เมือง']"); - await page.click('id=select-sub-district'); - await page.click("//span[text()='ช้างเผือก']"); - await page.fill('id=input-address-en', `20/0${i + 5}`); - await page.fill('id=input-regis-no', `282228222224${i + 5}`); - await page.click('id=input-start-date'); - await page.click(`//div[text()='1${i + 5}']`); - await page.click('id=input-retire-date'); - await page.click(`//div[text()='2${i + 5}']`); - await page.click('id=submitBtn'); - await page.click('id=btn-ok-dialog'); - } - await page.waitForTimeout(4000); + await page.click("(//div[@role='tab'])[3]"); + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + + // กรอกข้อมูลพื้นฐานของบุคคลากร + await page.click("//i[@aria-hidden='false']"); + await page.waitForSelector('id=select-hq-id', { + state: 'visible', + }); + await page.click('id=select-hq-id'); + await page.click("//span[normalize-space(text())='CMO00000']"); + + await page.waitForSelector('id=select-br-id', { state: 'visible' }); + await page.click('id=select-br-id'); + await page.click('id=select-br-id_4'); + await page.fill('id=input-username', 'courierw'); + await page.click('id=select-user-role'); + await page.click('id=select-user-role_6'); + // await page.click("//div[@role='option']"); + + // กรอกชื่อข้อมูลพื้นฐาน + await page.fill('id=input-citizen-id', '1282262422820'); + await page.click("//label[@for='form-dialog-personnel-select-prefix-name']"); + await page.click('id=form-dialog-personnel-select-prefix-name_0'); + await page.fill('id=form-dialog-personnel-input-first-name', 'มาตา'); + await page.fill('id=form-dialog-personnel-input-last-name', 'ลดา'); + await page.fill('id=form-dialog-personnel-input-first-name-en', 'Mata'); + await page.fill('id=form-dialog-personnel-input-last-name-en', 'Lada'); + await page.fill('id=form-dialog-personnel-input-telephone', '08422622282'); + await page.fill('id=form-dialog-personnel-input-email', 'employeew@mail.com'); + + // เลือกเพศ + await page.click('id=form-dialog-personnel-select-gender'); + await page.click("//span[text()='หญิง']"); + + // เลือกวันเกิด + await page.click('id=form-dialog-personnel-input-birth-date'); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='8']"); + + // วันออกบัตร วันที่หมออายุ + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-issue'])[1]", + ); + await page.click("//div[@id='2024-09-02']"); + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-expire'])[1]", + ); + await page.click("//div[@id='2024-09-15']/div[1]"); + + // กรอกที่อยู่ + await page.fill('id=drawer-info-personnel-input-address-no', '20/1'); + await page.click('id=drawer-info-personnel-select-province'); + await page.waitForSelector('id=drawer-info-personnel-select-province_6', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-province_6'); + await page.click('id=drawer-info-personnel-select-district'); + await page.waitForSelector('id=drawer-info-personnel-select-district_2', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-district_2'); + await page.click('id=drawer-info-personnel-select-sub-district'); + await page.waitForSelector('id=drawer-info-personnel-select-sub-district_1', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-sub-district_1'); + + // กรอกที่อยู่ภาษาอังกฤษ + await page.fill('id=drawer-info-personnel-input-address-en', '20/01'); + + // กรอกข้อมูลการทำงาน + await page.fill('id=input-regis-no', '2822282222421'); + await page.click('id=input-start-date'); + await page.click("//div[text()='11']"); + await page.click('id=input-retire-date'); + await page.click("//div[text()='21']"); + + // กดปุ่มเพื่อสร้างบุคคลากร + await page.click('id=btn-info-basic-save'); + await page.waitForTimeout(2000); + + // ดึงข้อมูลจาก Locator และนำ .textContent() เพื่อดึงมาแต่ข้อความจริง ๆ + const displayNameLocator = page.locator( + "//div[normalize-space(text())='มาตา ลดา']", + ); + const displayName = (await displayNameLocator.textContent())?.trim(); + + // ตรวจสอบข้อมูลที่ดึงออกมา + expect(displayName).toBe('มาตา ลดา'); + + console.log('ตรวจสอบการสร้างพนักงานส่งเอกสารหญิงถูกต้อง'); +}); + +test('Create Personnel พนักงานส่งเอกสาร ชาย', async () => { + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + + // กรอกข้อมูลพื้นฐานของบุคคลากร + await page.click("//i[@aria-hidden='false']"); + await page.waitForSelector('id=select-hq-id', { + state: 'visible', + }); + await page.click('id=select-hq-id'); + await page.click("//span[normalize-space(text())='CMO00000']"); + + await page.waitForSelector('id=select-br-id', { state: 'visible' }); + await page.click('id=select-br-id'); + await page.click('id=select-br-id_4'); + await page.fill('id=input-username', 'courierm'); + await page.click('id=select-user-role'); + await page.click('id=select-user-role_6'); + // await page.click("//div[@role='option']"); + + // กรอกชื่อข้อมูลพื้นฐาน + await page.fill('id=input-citizen-id', '1282262422820'); + await page.click("//label[@for='form-dialog-personnel-select-prefix-name']"); + await page.click('id=form-dialog-personnel-select-prefix-name_0'); + await page.fill('id=form-dialog-personnel-input-first-name', 'ธันวา'); + await page.fill('id=form-dialog-personnel-input-last-name', 'มานา'); + await page.fill('id=form-dialog-personnel-input-first-name-en', 'Thanwa'); + await page.fill('id=form-dialog-personnel-input-last-name-en', 'Mana'); + await page.fill('id=form-dialog-personnel-input-telephone', '08422622282'); + await page.fill('id=form-dialog-personnel-input-email', 'employeew@mail.com'); + + // เลือกเพศ + await page.click('id=form-dialog-personnel-select-gender'); + await page.click("//span[text()='ชาย']"); + + // เลือกวันเกิด + await page.click('id=form-dialog-personnel-input-birth-date'); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='8']"); + + // วันออกบัตร วันที่หมออายุ + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-issue'])[1]", + ); + await page.click("//div[@id='2024-09-02']"); + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-expire'])[1]", + ); + await page.click("//div[@id='2024-09-14']/div[1]"); + + // กรอกที่อยู่ + await page.fill('id=drawer-info-personnel-input-address-no', '20/1'); + await page.click('id=drawer-info-personnel-select-province'); + await page.waitForSelector('id=drawer-info-personnel-select-province_6', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-province_6'); + await page.click('id=drawer-info-personnel-select-district'); + await page.waitForSelector('id=drawer-info-personnel-select-district_2', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-district_2'); + await page.click('id=drawer-info-personnel-select-sub-district'); + await page.waitForSelector('id=drawer-info-personnel-select-sub-district_1', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-sub-district_1'); + + // กรอกที่อยู่ภาษาอังกฤษ + await page.fill('id=drawer-info-personnel-input-address-en', '20/01'); + + // กรอกข้อมูลการทำงาน + await page.fill('id=input-regis-no', '2822282222421'); + await page.click('id=input-start-date'); + await page.click("//div[text()='11']"); + await page.click('id=input-retire-date'); + await page.click("//div[text()='21']"); + + // กดปุ่มเพื่อสร้างบุคคลากร + await page.click('id=btn-info-basic-save'); + await page.waitForTimeout(2000); + + // ดึงข้อมูลจาก Locator และนำ .textContent() เพื่อดึงมาแต่ข้อความจริง ๆ + const displayNameLocator = page.locator( + "//div[normalize-space(text())='ธันวา มานา']", + ); + const displayName = (await displayNameLocator.textContent())?.trim(); + + // ตรวจสอบข้อมูลที่ดึงออกมา + expect(displayName).toBe('ธันวา มานา'); + + console.log('ตรวจสอบการสร้างพนักงานส่งเอกสารชายถูกต้อง'); }); test('Create Personnel ตัวแทน ชาย', async () => { - for (let i = 1; i < 5; i++) { - await page.click('id=btn-add'); - await page.click('id=btn-add-personne'); - await page.fill('id=input-username', `user00${i + 1}`); - await page.click('id=select-user-type'); - await page.click("//span[text()='ตัวแทน']"); - await page.click('id=select-user-role'); - await page.click("//span[text()='System']"); - await page.click("//div[@role='option']"); - await page.fill('id=input-first-name', `ทดสอบ${i + 1}`); - await page.fill('id=input-last-name', `ทดสอบ${i + 1}`); - await page.fill('id=input-first-name-en', `Firstname${i + 1}`); - await page.fill('id=input-last-name-en', `Lastname${i + 1}`); - await page.click('id=select-gender'); - await page.click("//span[text()='ชาย']"); - await page.click('id=input-birth-date'); - await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); - await page.click("//div[text()='2021']"); - await page.click("//div[text()='10']"); - await page.fill('id=input-address', `20/0${i + 1}`); - await page.click('id=select-province'); - await page.click("//span[text()='เชียงใหม่']"); - await page.click('id=select-district'); - await page.click("//span[text()='เมือง']"); - await page.click('id=select-sub-district'); - await page.click("//span[text()='ช้างเผือก']"); - await page.fill('id=input-address-en', `20/0${i + 1}`); - await page.click('id=submitBtn'); - await page.click('id=btn-ok-dialog'); - } - await page.waitForTimeout(4000); + await page.click("(//div[@role='tab'])[4]"); + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + + // กรอกข้อมูลพื้นฐานของบุคคลากร + await page.click("//i[@aria-hidden='false']"); + await page.waitForSelector('id=select-hq-id', { + state: 'visible', + }); + await page.click('id=select-hq-id'); + await page.click("//span[normalize-space(text())='CMO00000']"); + + await page.waitForSelector('id=select-br-id', { state: 'visible' }); + await page.click('id=select-br-id'); + await page.click('id=select-br-id_4'); + await page.fill('id=input-username', 'delegatem'); + await page.click('id=select-user-role'); + await page.click('id=select-user-role_8'); + // await page.click("//div[@role='option']"); + + // กรอกชื่อข้อมูลพื้นฐาน + await page.fill('id=input-citizen-id', '1282262422820'); + await page.click("//label[@for='form-dialog-personnel-select-prefix-name']"); + await page.click('id=form-dialog-personnel-select-prefix-name_0'); + await page.fill('id=form-dialog-personnel-input-first-name', 'อาคม'); + await page.fill('id=form-dialog-personnel-input-last-name', 'พลัง'); + await page.fill('id=form-dialog-personnel-input-first-name-en', 'Akom'); + await page.fill('id=form-dialog-personnel-input-last-name-en', 'Palang'); + await page.fill('id=form-dialog-personnel-input-telephone', '08422622282'); + await page.fill('id=form-dialog-personnel-input-email', 'employeew@mail.com'); + + // เลือกเพศ + await page.click('id=form-dialog-personnel-select-gender'); + await page.click("//span[text()='ชาย']"); + + // เลือกวันเกิด + await page.click('id=form-dialog-personnel-input-birth-date'); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='8']"); + + // วันออกบัตร วันที่หมออายุ + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-issue'])[1]", + ); + await page.click("//div[@id='2024-09-02']"); + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-expire'])[1]", + ); + await page.click("//div[@id='2024-09-13']/div[1]"); + + // กรอกที่อยู่ + await page.fill('id=drawer-info-personnel-input-address-no', '20/1'); + await page.click('id=drawer-info-personnel-select-province'); + await page.waitForSelector('id=drawer-info-personnel-select-province_6', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-province_6'); + await page.click('id=drawer-info-personnel-select-district'); + await page.waitForSelector('id=drawer-info-personnel-select-district_2', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-district_2'); + await page.click('id=drawer-info-personnel-select-sub-district'); + await page.waitForSelector('id=drawer-info-personnel-select-sub-district_1', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-sub-district_1'); + + // กรอกที่อยู่ภาษาอังกฤษ + await page.fill('id=drawer-info-personnel-input-address-en', '20/01'); + + // กรอกข้อมูลการทำงาน + await page.fill('id=input-discount-condition', 'ทดสอบข้อมูลการทำงาน'); + + // กดปุ่มเพื่อสร้างบุคคลากร + await page.click('id=btn-info-basic-save'); + await page.waitForTimeout(2000); + + // ดึงข้อมูลจาก Locator และนำ .textContent() เพื่อดึงมาแต่ข้อความจริง ๆ + const displayNameLocator = page.locator( + "//div[normalize-space(text())='อาคม พลัง']", + ); + const displayName = (await displayNameLocator.textContent())?.trim(); + + // ตรวจสอบข้อมูลที่ดึงออกมา + expect(displayName).toBe('อาคม พลัง'); + + console.log('ตรวจสอบการสร้างตัวแทนชายถูกต้อง'); }); test('Create Personnel ตัวแทน หญิง', async () => { - for (let i = 1; i < 10; i++) { - await page.click('id=btn-add'); - await page.click('id=btn-add-personne'); - await page.fill('id=input-username', `user00${i + 5}`); - await page.click('id=select-user-type'); - await page.click("//span[text()='ตัวแทน']"); - await page.click('id=select-user-role'); - await page.click("//span[text()='System']"); - await page.click("//div[@role='option']"); - await page.fill('id=input-first-name', `ทดสอบ${i + 5}`); - await page.fill('id=input-last-name', `ทดสอบ${i + 5}`); - await page.fill('id=input-first-name-en', `Firstname${i + 5}`); - await page.fill('id=input-last-name-en', `Lastname${i + 5}`); - await page.click('id=select-gender'); - await page.click("//span[text()='หญิง']"); - await page.click('id=input-birth-date'); - await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); - await page.click("//div[text()='2021']"); - await page.click("//div[text()='10']"); - await page.fill('id=input-address', `20/0${i + 5}`); - await page.click('id=select-province'); - await page.click("//span[text()='เชียงใหม่']"); - await page.click('id=select-district'); - await page.click("//span[text()='เมือง']"); - await page.click('id=select-sub-district'); - await page.click("//span[text()='ช้างเผือก']"); - await page.fill('id=input-address-en', `20/0${i + 5}`); - await page.click('id=submitBtn'); - await page.click('id=btn-ok-dialog'); - } - await page.waitForTimeout(4000); -}); + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); -test('Create Personnel เอเจนซี่ ชาย', async () => { - for (let i = 1; i < 5; i++) { - await page.click('id=btn-add'); - await page.click('id=btn-add-personne'); - await page.fill('id=input-username', `user000${i + 1}`); - await page.click('id=select-user-type'); - await page.click("//span[text()='เอเจนซี่']"); - await page.click('id=select-user-role'); - await page.click("//span[text()='System']"); - await page.click("//div[@role='option']"); - await page.fill('id=input-first-name', `ทดสอบ${i + 1}`); - await page.fill('id=input-last-name', `ทดสอบ${i + 1}`); - await page.fill('id=input-first-name-en', `Firstname${i + 1}`); - await page.fill('id=input-last-name-en', `Lastname${i + 1}`); - await page.click('id=select-gender'); - await page.click("//span[text()='ชาย']"); - await page.click('id=input-birth-date'); - await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); - await page.click("//div[text()='2021']"); - await page.click("//div[text()='10']"); - await page.fill('id=input-address', `20/0${i + 1}`); - await page.click('id=select-province'); - await page.click("//span[text()='เชียงใหม่']"); - await page.click('id=select-district'); - await page.click("//span[text()='เมือง']"); - await page.click('id=select-sub-district'); - await page.click("//span[text()='ช้างเผือก']"); - await page.fill('id=input-address-en', `20/0${i + 1}`); - await page.click('id=input-source-nationality'); - await page.click("(//span[text()='ไทย'])[2]"); - await page.click('id=input-import-nationality'); - await page.click("(//span[text()='ไทย'])[3]"); - await page.click('id=select-trainig-place'); - await page.click("//span[text()='สถานที่อบรมแรงงานเมียนมา-แม่สอด จ.ตาก']"); - await page.fill('id=input-checkpoint', 'แม่สอด'); - await page.fill('id=input-checkpoint-en', 'Maesod'); - await page.click('id=submitBtn'); - await page.click('id=btn-ok-dialog'); - } - await page.waitForTimeout(4000); + // กรอกข้อมูลพื้นฐานของบุคคลากร + await page.click("//i[@aria-hidden='false']"); + await page.waitForSelector('id=select-hq-id', { + state: 'visible', + }); + await page.click('id=select-hq-id'); + await page.click("//span[normalize-space(text())='CMO00000']"); + + await page.waitForSelector('id=select-br-id', { state: 'visible' }); + await page.click('id=select-br-id'); + await page.click('id=select-br-id_4'); + await page.fill('id=input-username', 'delegatew'); + await page.click('id=select-user-role'); + await page.click('id=select-user-role_10'); + // await page.click("//div[@role='option']"); + + // กรอกชื่อข้อมูลพื้นฐาน + await page.fill('id=input-citizen-id', '1282262422820'); + await page.click("//label[@for='form-dialog-personnel-select-prefix-name']"); + await page.click('id=form-dialog-personnel-select-prefix-name_0'); + await page.fill('id=form-dialog-personnel-input-first-name', 'สโรชา'); + await page.fill('id=form-dialog-personnel-input-last-name', 'มีนา'); + await page.fill('id=form-dialog-personnel-input-first-name-en', 'Sarocha'); + await page.fill('id=form-dialog-personnel-input-last-name-en', 'Mena'); + await page.fill('id=form-dialog-personnel-input-telephone', '08422622282'); + await page.fill('id=form-dialog-personnel-input-email', 'employeew@mail.com'); + + // เลือกเพศ + await page.click('id=form-dialog-personnel-select-gender'); + await page.click("//span[text()='หญิง']"); + + // เลือกวันเกิด + await page.click('id=form-dialog-personnel-input-birth-date'); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='8']"); + + // วันออกบัตร วันที่หมออายุ + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-issue'])[1]", + ); + await page.click("//div[@id='2024-09-02']"); + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-expire'])[1]", + ); + await page.click("//div[@id='2024-09-12']/div[1]"); + + // กรอกที่อยู่ + await page.fill('id=drawer-info-personnel-input-address-no', '20/1'); + await page.click('id=drawer-info-personnel-select-province'); + await page.waitForSelector('id=drawer-info-personnel-select-province_6', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-province_6'); + await page.click('id=drawer-info-personnel-select-district'); + await page.waitForSelector('id=drawer-info-personnel-select-district_2', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-district_2'); + await page.click('id=drawer-info-personnel-select-sub-district'); + await page.waitForSelector('id=drawer-info-personnel-select-sub-district_1', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-sub-district_1'); + + // กรอกที่อยู่ภาษาอังกฤษ + await page.fill('id=drawer-info-personnel-input-address-en', '20/01'); + + // กรอกข้อมูลการทำงาน + await page.fill('id=input-discount-condition', 'ทดสอบข้อมูลการทำงาน'); + + // กดปุ่มเพื่อสร้างบุคคลากร + await page.click('id=btn-info-basic-save'); + await page.waitForTimeout(2000); + + // ดึงข้อมูลจาก Locator และนำ .textContent() เพื่อดึงมาแต่ข้อความจริง ๆ + const displayNameLocator = page.locator( + "//div[normalize-space(text())='สโรชา มีนา']", + ); + const displayName = (await displayNameLocator.textContent())?.trim(); + + // ตรวจสอบข้อมูลที่ดึงออกมา + expect(displayName).toBe('สโรชา มีนา'); + + console.log('ตรวจสอบการสร้างตัวแทนหญิงถูกต้อง'); }); test('Create Personnel เอเจนซี่ หญิง', async () => { - for (let i = 1; i < 10; i++) { - await page.click('id=btn-add'); - await page.click('id=btn-add-personne'); - await page.fill('id=input-username', `user000${i + 5}`); - await page.click('id=select-user-type'); - await page.click("//span[text()='เอเจนซี่']"); - await page.click('id=select-user-role'); - await page.click("//span[text()='System']"); - await page.click("//div[@role='option']"); - await page.fill('id=input-first-name', `ทดสอบ${i + 5}`); - await page.fill('id=input-last-name', `ทดสอบ${i + 5}`); - await page.fill('id=input-first-name-en', `Firstname${i + 5}`); - await page.fill('id=input-last-name-en', `Lastname${i + 5}`); - await page.click('id=select-gender'); - await page.click("//span[text()='หญิง']"); - await page.click('id=input-birth-date'); - await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); - await page.click("//div[text()='2021']"); - await page.click("//div[text()='10']"); - await page.fill('id=input-address', `20/0${i + 5}`); - await page.click('id=select-province'); - await page.click("//span[text()='เชียงใหม่']"); - await page.click('id=select-district'); - await page.click("//span[text()='เมือง']"); - await page.click('id=select-sub-district'); - await page.click("//span[text()='ช้างเผือก']"); - await page.fill('id=input-address-en', `20/0${i + 5}`); - await page.click('id=input-source-nationality'); - await page.click("(//span[text()='ไทย'])[2]"); - await page.click('id=input-import-nationality'); - await page.click("(//span[text()='ไทย'])[3]"); - await page.click('id=select-trainig-place'); - await page.click("//span[text()='สถานที่อบรมแรงงานเมียนมา-แม่สอด จ.ตาก']"); - await page.fill('id=input-checkpoint', 'แม่สอด'); - await page.fill('id=input-checkpoint-en', 'Maesod'); - await page.click('id=submitBtn'); - await page.click('id=btn-ok-dialog'); - } - await page.waitForTimeout(4000); + await page.click("(//div[@role='tab'])[5]"); + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + + // กรอกข้อมูลพื้นฐานของบุคคลากร + await page.click("//i[@aria-hidden='false']"); + await page.waitForSelector('id=select-hq-id', { + state: 'visible', + }); + await page.click('id=select-hq-id'); + await page.click("//span[normalize-space(text())='CMO00000']"); + + await page.waitForSelector('id=select-br-id', { state: 'visible' }); + await page.click('id=select-br-id'); + await page.click('id=select-br-id_4'); + await page.fill('id=input-username', 'agencyw'); + await page.click('id=select-user-role'); + await page.click('id=select-user-role_2'); + // await page.click("//div[@role='option']"); + + // กรอกชื่อข้อมูลพื้นฐาน + await page.fill('id=input-citizen-id', '1282262422820'); + await page.click("//label[@for='form-dialog-personnel-select-prefix-name']"); + await page.click('id=form-dialog-personnel-select-prefix-name_0'); + await page.fill('id=form-dialog-personnel-input-first-name', 'ธิดา'); + await page.fill('id=form-dialog-personnel-input-last-name', 'งามตา'); + await page.fill('id=form-dialog-personnel-input-first-name-en', 'Thida'); + await page.fill('id=form-dialog-personnel-input-last-name-en', 'Yamta'); + await page.fill('id=form-dialog-personnel-input-telephone', '08422622282'); + await page.fill('id=form-dialog-personnel-input-email', 'employeew@mail.com'); + + // เลือกเพศ + await page.click('id=form-dialog-personnel-select-gender'); + await page.click("//span[text()='หญิง']"); + + // เลือกวันเกิด + await page.click('id=form-dialog-personnel-input-birth-date'); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='8']"); + + // วันออกบัตร วันที่หมออายุ + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-issue'])[1]", + ); + await page.click("//div[@id='2024-09-02']"); + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-expire'])[1]", + ); + await page.click("//div[@id='2024-09-11']/div[1]"); + + // กรอกที่อยู่ + await page.fill('id=drawer-info-personnel-input-address-no', '20/1'); + await page.click('id=drawer-info-personnel-select-province'); + await page.waitForSelector('id=drawer-info-personnel-select-province_6', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-province_6'); + await page.click('id=drawer-info-personnel-select-district'); + await page.waitForSelector('id=drawer-info-personnel-select-district_2', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-district_2'); + await page.click('id=drawer-info-personnel-select-sub-district'); + await page.waitForSelector('id=drawer-info-personnel-select-sub-district_1', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-sub-district_1'); + + // กรอกที่อยู่ภาษาอังกฤษ + await page.fill('id=drawer-info-personnel-input-address-en', '20/01'); + + // กรอกข้อมูลการทำงาน + await page.click('id=input-source-nationality'); + await page.click("(//div[@role='option'])[1]"); + await page.click('id=input-import-nationality'); + await page.click("(//div[@role='option'])[1]"); + await page.click('id=select-trainig-place'); + await page.click("//span[text()='สถานที่อบรมแรงงานเมียนมา-แม่สอด จ.ตาก']"); + await page.fill('id=input-checkpoint', 'แม่สอด'); + await page.fill('id=input-checkpoint-en', 'Maesod'); + + // กดปุ่มเพื่อสร้างบุคคลากร + await page.click('id=btn-info-basic-save'); + await page.waitForTimeout(2000); + + // ดึงข้อมูลจาก Locator และนำ .textContent() เพื่อดึงมาแต่ข้อความจริง ๆ + const displayNameLocator = page.locator( + "//div[normalize-space(text())='ธิดา งามตา']", + ); + const displayName = (await displayNameLocator.textContent())?.trim(); + + // ตรวจสอบข้อมูลที่ดึงออกมา + expect(displayName).toBe('ธิดา งามตา'); + + console.log('ตรวจสอบการสร้างเอเจนซี่หญิงถูกต้อง'); +}); + +test('Create Personnel เอเจนซี่ ชาย', async () => { + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + + // กรอกข้อมูลพื้นฐานของบุคคลากร + await page.click("//i[@aria-hidden='false']"); + await page.waitForSelector('id=select-hq-id', { + state: 'visible', + }); + await page.click('id=select-hq-id'); + await page.click("//span[normalize-space(text())='CMO00000']"); + + await page.waitForSelector('id=select-br-id', { state: 'visible' }); + await page.click('id=select-br-id'); + await page.click('id=select-br-id_4'); + await page.fill('id=input-username', 'agencym'); + await page.click('id=select-user-role'); + await page.click('id=select-user-role_8'); + // await page.click("//div[@role='option']"); + + // กรอกชื่อข้อมูลพื้นฐาน + await page.fill('id=input-citizen-id', '1282262422820'); + await page.click("//label[@for='form-dialog-personnel-select-prefix-name']"); + await page.click('id=form-dialog-personnel-select-prefix-name_0'); + await page.fill('id=form-dialog-personnel-input-first-name', 'อันดา'); + await page.fill('id=form-dialog-personnel-input-last-name', 'ธรรมา'); + await page.fill('id=form-dialog-personnel-input-first-name-en', 'Aunda'); + await page.fill('id=form-dialog-personnel-input-last-name-en', 'Thamma'); + await page.fill('id=form-dialog-personnel-input-telephone', '08422622282'); + await page.fill('id=form-dialog-personnel-input-email', 'employeew@mail.com'); + + // เลือกเพศ + await page.click('id=form-dialog-personnel-select-gender'); + await page.click("//span[text()='ชาย']"); + + // เลือกวันเกิด + await page.click('id=form-dialog-personnel-input-birth-date'); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='8']"); + + // วันออกบัตร วันที่หมออายุ + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-issue'])[1]", + ); + await page.click("//div[@id='2024-09-02']"); + await page.click( + "(//input[@id='form-dialog-personnel-input-citizen-expire'])[1]", + ); + await page.click("//div[@id='2024-09-10']/div[1]"); + + // กรอกที่อยู่ + await page.fill('id=drawer-info-personnel-input-address-no', '20/1'); + await page.click('id=drawer-info-personnel-select-province'); + await page.waitForSelector('id=drawer-info-personnel-select-province_6', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-province_6'); + await page.click('id=drawer-info-personnel-select-district'); + await page.waitForSelector('id=drawer-info-personnel-select-district_2', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-district_2'); + await page.click('id=drawer-info-personnel-select-sub-district'); + await page.waitForSelector('id=drawer-info-personnel-select-sub-district_1', { + state: 'visible', + }); + await page.click('id=drawer-info-personnel-select-sub-district_1'); + + // กรอกที่อยู่ภาษาอังกฤษ + await page.fill('id=drawer-info-personnel-input-address-en', '20/01'); + + // กรอกข้อมูลการทำงาน + await page.click('id=input-source-nationality'); + await page.click("(//div[@role='option'])[1]"); + await page.click('id=input-import-nationality'); + await page.click("(//div[@role='option'])[1]"); + await page.click('id=select-trainig-place'); + await page.click("//span[text()='สถานที่อบรมแรงงานเมียนมา-แม่สอด จ.ตาก']"); + await page.fill('id=input-checkpoint', 'แม่สอด'); + await page.fill('id=input-checkpoint-en', 'Maesod'); + + // กดปุ่มเพื่อสร้างบุคคลากร + await page.click('id=btn-info-basic-save'); + await page.waitForTimeout(2000); + + // ดึงข้อมูลจาก Locator และนำ .textContent() เพื่อดึงมาแต่ข้อความจริง ๆ + const displayNameLocator = page.locator( + "//div[normalize-space(text())='อันดา ธรรมา']", + ); + const displayName = (await displayNameLocator.textContent())?.trim(); + + // ตรวจสอบข้อมูลที่ดึงออกมา + expect(displayName).toBe('อันดา ธรรมา'); + + console.log('ตรวจสอบการสร้างเอเจนซี่ชายถูกต้อง'); }); diff --git a/tests/02-Admin-PersonnelManagement/JWS_PM_002_CreatePersonnelFail.spec.ts b/tests/02-Admin-PersonnelManagement/JWS_PM_002_CreatePersonnelFail.spec.ts new file mode 100644 index 00000000..ec57ab11 --- /dev/null +++ b/tests/02-Admin-PersonnelManagement/JWS_PM_002_CreatePersonnelFail.spec.ts @@ -0,0 +1,128 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; +import exp from 'constants'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Create Personnel - ในกรณีที่ไม่กรอกข้อมูล', async () => { + await page.click('id=menu-icon-personnel-management'); + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + await page.click('id=btn-info-basic-save'); + await page.waitForTimeout(2000); + + const usernameError = page.locator("(//div[@role='alert'])[1]"); + const userTypeError = page.locator("(//div[@role='alert'])[2]"); + const userPermisionError = page.locator("(//div[@role='alert'])[3]"); + const citizenIdError = page.locator("(//div[@role='alert'])[4]"); + const firstNameError = page.locator("(//div[@role='alert'])[5]"); + const lastNameError = page.locator("(//div[@role='alert'])[6]"); + const firstNameEnError = page.locator("(//div[@role='alert'])[7]"); + const lastNameEnError = page.locator("(//div[@role='alert'])[8]"); + const brithDateError = page.locator("(//div[@role='alert'])[9]"); + const citizenIdInError = page.locator("(//div[@role='alert'])[10]"); + const addressError = page.locator("(//div[@role='alert'])[11]"); + const provinceError = page.locator("(//div[@role='alert'])[12]"); + const districtError = page.locator("(//div[@role='alert'])[13]"); + const subDistrictErrorError = page.locator("(//div[@role='alert'])[14]"); + const addressEnErrorError = page.locator("(//div[@role='alert'])[15]"); + + await expect(usernameError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + await expect(userTypeError).toHaveText('โปรดเลือกประเภทผู้ใช้งาน'); + await expect(userPermisionError).toHaveText('โปรดเลือกสิทธิ์ผู้ใช้งาน'); + await expect(citizenIdError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + await expect(firstNameError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + await expect(lastNameError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + await expect(firstNameEnError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + await expect(lastNameEnError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + await expect(brithDateError).toHaveText('โปรดเลือกวันเดือนปีเกิด'); + await expect(citizenIdInError).toHaveText('โปรดเลือกวันที่ออกบัตร'); + await expect(addressError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + await expect(provinceError).toHaveText('โปรดเลือกจังหวัด'); + await expect(districtError).toHaveText('โปรดเลือกอำเภอ'); + await expect(subDistrictErrorError).toHaveText('โปรดเลือกตำบล'); + await expect(addressEnErrorError).toHaveText('จำเป็นต้องกรอกข้อมูลนี้'); + + await page.waitForTimeout(2000); + await page.click('id=btn-form-close'); + console.log('การตรวจสอบการทำงานถูกต้อง'); +}); + +test('Create Personnel - ในกรณีที่กรอกชื่อผู้ใช้งานที่ไม่ตรงกับตัวอักษรที่กำหนด', async () => { + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + + // กรอกชื่อผู้ใช้งาน + await page.fill('id=input-username', 'ทดสอบ'); + + const usernameError = page.locator("(//div[@role='alert'])[1]"); + + await expect(usernameError).toHaveText( + 'โปรดใช้เฉพาะตัวอักษรภาษาอังกฤษและตัวเลขเท่านั้น', + ); + + await page.waitForTimeout(2000); + await page.click('id=btn-form-close'); + console.log('การตรวจสอบการทำงานถูกต้อง'); +}); + +test('Create Personnel - ในกรณีที่กรอกชื่อและนามสกุลภาษาอังกฤษไม่ตรงตามรูปแบบ', async () => { + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + + // กรอกชื่อผู้ใช้งาน + await page.fill('id=form-dialog-personnel-input-first-name-en', 'ทดสอบ'); + await page.fill('id=form-dialog-personnel-input-last-name-en', 'ทดสอบ'); + + const firstNameEnError = page.locator("(//div[@role='alert'])[1]"); + const lastNameEnError = page.locator("(//div[@role='alert'])[2]"); + + await expect(firstNameEnError).toHaveText( + 'โปรดใช้เฉพาะตัวอักษรภาษาอังกฤษเท่านั้น', + ); + await expect(lastNameEnError).toHaveText( + 'โปรดใช้เฉพาะตัวอักษรภาษาอังกฤษเท่านั้น', + ); + + await page.waitForTimeout(2000); + await page.click('id=btn-form-close'); + console.log('การตรวจสอบการทำงานถูกต้อง'); +}); + +test('Create Personnel - ในกรณีที่กรอกอีเมลไม่ตรงรูปแบบ', async () => { + await page.click('id=menu-icon-personnel-management'); + await page.click('id=btn-add'); + await page.click('id=btn-add-personne'); + + // กรอกชื่อผู้ใช้งาน + await page.fill('id=form-dialog-personnel-input-email', 'ทดสอบ'); + + const firstNameEnError = page.locator("(//div[@role='alert'])[1]"); + + await expect(firstNameEnError).toHaveText('ข้อมูลไม่ถูกต้อง'); + + await page.waitForTimeout(2000); + await page.click('id=btn-form-close'); + console.log('การตรวจสอบการทำงานถูกต้อง'); +}); diff --git a/tests/02-Admin-PersonnelManagement/JWS_PM_003_ViewDetail.spec.ts b/tests/02-Admin-PersonnelManagement/JWS_PM_003_ViewDetail.spec.ts new file mode 100644 index 00000000..0829467d --- /dev/null +++ b/tests/02-Admin-PersonnelManagement/JWS_PM_003_ViewDetail.spec.ts @@ -0,0 +1,109 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('View Deatil Personnel Employee', async () => { + await page.click('id=menu-icon-personnel-management'); + await page.click("(//div[@role='tab'])[2]"); + + try { + await page.waitForSelector('id=btn-kebab-action-employeem', { + state: 'visible', + }); + await page.click('id=btn-kebab-action-employeem'); + await page.click('id=btn-kebab-view-detail-employeem'); + + const detailTitle = page.locator("//span[text()='ธรรมรงด์ ดำรงธรรม']"); + + await expect(detailTitle).toHaveText('ธรรมรงด์ ดำรงธรรม'); + console.log('ตรวจสอบรายละเอียดพนักงานถูกต้อง'); + } catch (error) { + console.log('เกิดข้อผิดพลาดในการทดสอบ'); + throw error; + } + + await page.waitForTimeout(2000); + await page.click('id=btn-info-close'); +}); + +test('View Deatil Personnel Courier', async () => { + try { + await page.click("(//div[@role='tab'])[3]"); + await page.click('id=btn-kebab-action-courierw'); + await page.click('id=btn-kebab-view-detail-courierw'); + + const detailTitle = page.locator("//span[text()='มาตา ลดา']"); + + await expect(detailTitle).toHaveText('มาตา ลดา'); + console.log('ตรวจสอบรายละเอียดพนักงานส่งเอกสารถูกต้อง'); + } catch (error) { + console.log('เกิดข้อผิดพลาดในการทดสอบ'); + throw error; + } + + await page.waitForTimeout(2000); + await page.click('id=btn-info-close'); +}); + +test('View Deatil Personnel Delegate', async () => { + try { + await page.click("(//div[@role='tab'])[4]"); + await page.click('id=btn-kebab-action-delegatem'); + await page.click('id=btn-kebab-view-detail-delegatem'); + + const detailTitle = page.locator("//span[text()='อาคม พลัง']"); + + await expect(detailTitle).toHaveText('อาคม พลัง'); + console.log('ตรวจสอบรายละเอียดตัวแทนถูกต้อง'); + } catch (error) { + console.log('เกิดข้อผิดพลาดในการทดสอบ'); + throw error; + } + + await page.waitForTimeout(2000); + await page.click('id=btn-info-close'); +}); + +test('View Deatil Personnel Agency', async () => { + try { + await page.click("(//div[@role='tab'])[5]"); + await page.click('id=btn-kebab-action-agencyw'); + await page.waitForSelector('id=btn-kebab-view-detail-agencyw', { + state: 'visible', + }); + await page.click('id=btn-kebab-view-detail-agencyw'); + + const detailTitle = await page.locator("//span[text()='ธิดา งามตา']"); + + await expect(detailTitle).toHaveText('ธิดา งามตา'); + console.log('ตรวจสอบรายละเอียดเอเจนซี่ถูกต้อง'); + } catch (error) { + console.log('เกิดข้อผิดพลาดในการทดสอบ'); + throw error; + } + + await page.waitForTimeout(2000); + await page.click('id=btn-info-close'); +}); diff --git a/tests/02-Admin-PersonnelManagement/JWS_PM_004_EditPersonnel.spec.ts b/tests/02-Admin-PersonnelManagement/JWS_PM_004_EditPersonnel.spec.ts new file mode 100644 index 00000000..6150116b --- /dev/null +++ b/tests/02-Admin-PersonnelManagement/JWS_PM_004_EditPersonnel.spec.ts @@ -0,0 +1,243 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; +import { exec } from 'child_process'; +import { log } from 'console'; +import { writeFileSync } from 'fs'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Edit Personnel - พนักงาน', async () => { + await page.click('id=menu-icon-personnel-management'); + + try { + // เข้าสู่หน้าแก้ไขพนักงาน + await page.click("(//div[@role='tab'])[2]"); + await page.waitForSelector('id=btn-kebab-action-employeem', { + state: 'visible', + }); + await page.click('id=btn-kebab-action-employeem'); + + // ตรวจสอบการคลิกว่าได้มีการคลิกหรือการแสดงจริงหรือไม่ + // const isElementVisible = await page.isVisible( + // 'id=btn-kebab-edit-employeem', + // ); + // console.log('Element visibility:', isElementVisible); + + await page.click('id=btn-kebab-edit-employeem'); + + // แก้ไขข้อมูล + await page.fill('id=drawer-info-personnel-input-first-name', 'อานน'); + await page.fill('id=drawer-info-personnel-input-last-name', 'รักมาก'); + await page.fill('id=drawer-info-personnel-input-first-name-en', 'Arnon'); + await page.fill('id=drawer-info-personnel-input-last-name-en', 'Rakmak'); + await page.click('id=btn-info-basic-save'); // คลิกปุ่มบันทึก + + // ตรวจสอบหลังแก้ไขเสร็จ + await page.waitForSelector('id=btn-kebab-action-employeem', { + state: 'visible', + }); + await page.click('id=btn-kebab-action-employeem'); + await page.waitForSelector('id=btn-kebab-view-detail-employeem', { + state: 'visible', + }); + await page.click('id=btn-kebab-view-detail-employeem'); + + // ตรวจสอบข้อมูลว่าทำการแก้ไขถูกหรือไม่ + const detailEditFistName = await page.inputValue("//input[@value='อานน']"); + const detailEditLastName = await page.inputValue( + "//input[@value='รักมาก']", + ); + const detailEditFistNameEn = await page.inputValue( + "//input[@value='Arnon']", + ); + const detailEditLastNameEn = await page.inputValue( + "//input[@value='Rakmak']", + ); + + await expect(detailEditFistName).toBe('อานน'); + await expect(detailEditLastName).toBe('รักมาก'); + await expect(detailEditFistNameEn).toBe('Arnon'); + await expect(detailEditLastNameEn).toBe('Rakmak'); + + console.log('ตรวจสอบการแก้ไขข้อมูลพนักงานถูกต้อง'); + } catch (error) { + console.log('เกิดข้อผิดพลาดในการทดสอบแก้ไขบุคลากร'); + throw error; + } + await page.waitForTimeout(4000); + await page.click('id=btn-info-close'); +}); + +test('Edit Personnel - พนักงานส่งเอกสาร', async () => { + try { + // เข้าสู่หน้าแก้ไขพนักงาน + await page.click("(//div[@role='tab'])[3]"); + await page.click('id=btn-kebab-action-courierw'); + await page.click('id=btn-kebab-edit-courierw'); + + // แก้ไขข้อมูล + await page.fill('id=drawer-info-personnel-input-first-name', 'ลาดา'); + await page.fill('id=drawer-info-personnel-input-last-name', 'มดา'); + await page.fill('id=drawer-info-personnel-input-first-name-en', 'Lada'); + await page.fill('id=drawer-info-personnel-input-last-name-en', 'Mada'); + await page.click('id=btn-info-basic-save'); // คลิกปุ่มบันทึก + + // ตรวจสอบหลังแก้ไขเสร็จ + await page.waitForSelector('id=btn-kebab-action-courierw', { + state: 'visible', + }); + await page.click('id=btn-kebab-action-courierw'); + await page.waitForSelector('id=btn-kebab-view-detail-courierw', { + state: 'visible', + }); + await page.click('id=btn-kebab-view-detail-courierw'); + + // ตรวจสอบข้อมูลว่าทำการแก้ไขถูกหรือไม่ + const detailEditFistName = await page.inputValue("//input[@value='ลาดา']"); + const detailEditLastName = await page.inputValue("//input[@value='มดา']"); + const detailEditFistNameEn = await page.inputValue( + "//input[@value='Lada']", + ); + const detailEditLastNameEn = await page.inputValue( + "//input[@value='Mada']", + ); + + await expect(detailEditFistName).toBe('ลาดา'); + await expect(detailEditLastName).toBe('มดา'); + await expect(detailEditFistNameEn).toBe('Lada'); + await expect(detailEditLastNameEn).toBe('Mada'); + + console.log('ตรวจสอบการแก้ไขข้อมูลพนักงานส่งเอกสารถูกต้อง'); + } catch (error) { + console.log('เกิดข้อผิดพลาดในการทดสอบแก้ไขบุคลากร'); + throw error; + } + await page.waitForTimeout(4000); + await page.click('id=btn-info-close'); +}); + +test('Edit Personnel - ตัวแทน', async () => { + try { + // เข้าสู่หน้าแก้ไขพนักงาน + await page.click("(//div[@role='tab'])[4]"); + await page.click('id=btn-kebab-action-delegatem'); + await page.click('id=btn-kebab-edit-delegatem'); + + // แก้ไขข้อมูล + await page.fill('id=drawer-info-personnel-input-first-name', 'ธนกร'); + await page.fill('id=drawer-info-personnel-input-last-name', 'ลอยฟ้า'); + await page.fill( + 'id=drawer-info-personnel-input-first-name-en', + 'Thanakorn', + ); + await page.fill('id=drawer-info-personnel-input-last-name-en', 'Loifa'); + await page.click('id=btn-info-basic-save'); // คลิกปุ่มบันทึก + + // ตรวจสอบหลังแก้ไขเสร็จ + await page.waitForSelector('id=btn-kebab-action-delegatem', { + state: 'visible', + }); + await page.click('id=btn-kebab-action-delegatem'); + await page.waitForSelector('id=btn-kebab-view-detail-delegatem', { + state: 'visible', + }); + await page.click('id=btn-kebab-view-detail-delegatem'); + + // ตรวจสอบข้อมูลว่าทำการแก้ไขถูกหรือไม่ + const detailEditFistName = await page.inputValue("//input[@value='ธนกร']"); + const detailEditLastName = await page.inputValue( + "//input[@value='ลอยฟ้า']", + ); + const detailEditFistNameEn = await page.inputValue( + "//input[@value='Thanakorn']", + ); + const detailEditLastNameEn = await page.inputValue( + "//input[@value='Loifa']", + ); + + await expect(detailEditFistName).toBe('ธนกร'); + await expect(detailEditLastName).toBe('ลอยฟ้า'); + await expect(detailEditFistNameEn).toBe('Thanakorn'); + await expect(detailEditLastNameEn).toBe('Loifa'); + + console.log('ตรวจสอบการแก้ไขข้อมูลตัวแทนถูกต้อง'); + } catch (error) { + console.log('เกิดข้อผิดพลาดในการทดสอบแก้ไขบุคลากร'); + throw error; + } + await page.waitForTimeout(4000); + await page.click('id=btn-info-close'); +}); + +test('Edit Personnel - เอเจนซี่', async () => { + try { + // เข้าสู่หน้าแก้ไขพนักงาน + await page.click("(//div[@role='tab'])[5]"); + await page.waitForTimeout(2000); + await page.waitForSelector('id=btn-kebab-action-agencyw', { + state: 'visible', + }); + await page.click('id=btn-kebab-action-agencyw'); + await page.click('id=btn-kebab-edit-agencyw'); + + // แก้ไขข้อมูล + await page.fill('id=drawer-info-personnel-input-first-name', 'นิดา'); + await page.fill('id=drawer-info-personnel-input-last-name', 'อามา'); + await page.fill('id=drawer-info-personnel-input-first-name-en', 'Nida'); + await page.fill('id=drawer-info-personnel-input-last-name-en', 'Arma'); + await page.click('id=btn-info-basic-save'); // คลิกปุ่มบันทึก + + // ตรวจสอบหลังแก้ไขเสร็จ + await page.waitForSelector('id=btn-kebab-action-agencyw', { + state: 'visible', + }); + await page.click('id=btn-kebab-action-agencyw'); + await page.waitForSelector('id=btn-kebab-view-detail-agencyw', { + state: 'visible', + }); + await page.click('id=btn-kebab-view-detail-agencyw'); + + // ตรวจสอบข้อมูลว่าทำการแก้ไขถูกหรือไม่ + const detailEditFistName = await page.inputValue("//input[@value='นิดา']"); + const detailEditLastName = await page.inputValue("//input[@value='อามา']"); + const detailEditFistNameEn = await page.inputValue( + "//input[@value='Nida']", + ); + const detailEditLastNameEn = await page.inputValue( + "//input[@value='Arma']", + ); + + await expect(detailEditFistName).toBe('นิดา'); + await expect(detailEditLastName).toBe('อามา'); + await expect(detailEditFistNameEn).toBe('Nida'); + await expect(detailEditLastNameEn).toBe('Arma'); + + console.log('ตรวจสอบการแก้ไขข้อมูลเอเจนซี่ถูกต้อง'); + } catch (error) { + console.log('เกิดข้อผิดพลาดในการทดสอบแก้ไขบุคลากร'); + throw error; + } + await page.waitForTimeout(4000); + await page.click('id=btn-info-close'); +}); diff --git a/tests/02-Admin-PersonnelManagement/JWS_PM_005_StatusPersonnel.spec.ts b/tests/02-Admin-PersonnelManagement/JWS_PM_005_StatusPersonnel.spec.ts new file mode 100644 index 00000000..df83e61e --- /dev/null +++ b/tests/02-Admin-PersonnelManagement/JWS_PM_005_StatusPersonnel.spec.ts @@ -0,0 +1,98 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('ปิดสถานะการใช้งานบุคลากร', async () => { + await page.click('id=menu-icon-personnel-management'); + try { + await page.click('id=btn-kebab-action-employeem'); + + await page.click('id=btn-kebab-status-employeem', { + force: true, + }); + await page.click('id=btn-ok-dialog'); + console.log('เปลี่ยนสถานะสำเร็จ'); + await page.reload(); + + // รอ Update + await page.waitForTimeout(2000); + console.log('สถานะถูกเปลี่ยนแล้ว'); + + // ตรวจสอบสีของแถวหลังจากทำการเปลี่ยนสถานะ + const rowLocator = page.locator( + "//div[normalize-space(text())='อานน รักมาก']", + ); + const backgroundColor = await rowLocator.evaluate( + (el) => window.getComputedStyle(el).backgroundColor, + ); + + // กำหนดสีหลัเปลี่ยนสถานะการใช้งาน + const expectedColor = 'rgba(0, 0, 0, 0)'; + + // ตรวจสอบสีที่เปลี่ยนไป + expect(backgroundColor.trim()).toBe(expectedColor); + console.log('สีของแถวถูกเปลี่ยนเป็นสีเทาอ่อน'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ'); + throw error; + } + await page.waitForTimeout(2000); +}); + +test('เปิดสถานะการใช้งานบุคลากร', async () => { + try { + await page.click('id=btn-kebab-action-employeem'); + + await page.click('id=btn-kebab-status-employeem', { + force: true, + }); + await page.click('id=btn-ok-dialog'); + console.log('เปลี่ยนสถานะสำเร็จ'); + await page.reload(); + + // รอ Update + await page.waitForTimeout(2000); + console.log('สถานะถูกเปลี่ยนแล้ว'); + + // ตรวจสอบสีของแถวหลังจากทำการเปลี่ยนสถานะ + const rowLocator = page.locator( + "//div[normalize-space(text())='อานน รักมาก']", + ); + const backgroundColor = await rowLocator.evaluate( + (el) => window.getComputedStyle(el).backgroundColor, + ); + + // กำหนดสีหลัเปลี่ยนสถานะการใช้งาน + const expectedColor = 'rgba(0, 0, 0, 0)'; + + // ตรวจสอบสีที่เปลี่ยนไป + expect(backgroundColor.trim()).toBe(expectedColor); + console.log('สีของแถวถูกเปลี่ยนเป็นของสถานะการใช้งาน'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ'); + throw error; + } + await page.waitForTimeout(2000); +}); diff --git a/tests/02-Admin-PersonnelManagement/JWS_PM_005_SearchPersonnel.spec.ts b/tests/02-Admin-PersonnelManagement/JWS_PM_006_SearchPersonnel(ยังไม่เสร็จทำทีหลัง).spec.ts similarity index 100% rename from tests/02-Admin-PersonnelManagement/JWS_PM_005_SearchPersonnel.spec.ts rename to tests/02-Admin-PersonnelManagement/JWS_PM_006_SearchPersonnel(ยังไม่เสร็จทำทีหลัง).spec.ts diff --git a/tests/02-Admin-PersonnelManagement/JWS_PM_007_StatusPersonnelType.spec.ts b/tests/02-Admin-PersonnelManagement/JWS_PM_007_StatusPersonnelType.spec.ts new file mode 100644 index 00000000..2ec0c54e --- /dev/null +++ b/tests/02-Admin-PersonnelManagement/JWS_PM_007_StatusPersonnelType.spec.ts @@ -0,0 +1,355 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('ตรวจสอบการแสดงสถานะใช้งาน เปิด/ปิด บุคลากรทั้งหมด', async () => { + try { + // คลิกเมนูจัดการบุคลากร + await page.click('id=menu-icon-personnel-management'); + + // แสดงสถานะที่ใช้งาน + // คลิกเพื่อเปิด dropdown + await page.click('id=field-select-status'); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อแสดงสถานะกำลังใช้งานอยู่ + await page.click('id=field-select-status_1'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่ามีแต่สถานะใช้งานหรือไม่ + const statusActive = await page.isVisible('id=field-select-status_1'); + + console.log('มีเพียงสถานะการใช้งานเท่านั้น', statusActive); // เช็ค + + expect(statusActive).toBe(false); + + console.log('ตรวจสอบสถานะการใช้งานมีแต่สถานะกำลังใช้งานเท่านั้น'); + + // แสดงสถานะที่ไม่ใช้งาน + // คลิกเพื่อเปิด dropdown + await page.keyboard.press('Escape'); + await page.click('id=field-select-status'); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อแสดงสถานะกำลังไม่ใช้งาน + await page.click('id=field-select-status_2'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่ามีแต่สถานะไม่ใช้งานหรือไม่ + const statusInActive = await page.isVisible('id=field-select-status_1'); + + console.log('มีเพียงสถานะการใช้งานเท่านั้น', statusInActive); // เช็ค + + expect(statusActive).toBe(false); + + console.log('ตรวจสอบสถานะการใช้งานมีแต่สถานะที่ไม่ใช้งาน'); + + // แสดงสถานะทั้งหมด + // คลิกเพื่อเปิด dropdown + await page.keyboard.press('Escape'); + await page.click('id=field-select-status'); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อแสดงสถานะทั้งหมด + await page.click('id=field-select-status_0'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าแสดงทุกสถานะหรือไม่ + const statusAll = await page.isVisible('id=field-select-status_1'); + + console.log('สถานะทั้งหมด', statusAll); // เช็ค + + expect(statusActive).toBe(false); + + console.log('ตรวจสอบสถานะทั้งหมด'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } +}); + +test('ตรวจสอบการแสดงสถานะใช้งาน เปิด/ปิด พนักงาน', async () => { + try { + // คลิก Tab พนักงาน + await page.click("(//div[@role='tab'])[2]"); + + // แสดงสถานะที่ใช้งาน + // คลิกเพื่อเปิด dropdown + await page.click('id=field-select-status'); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อแสดงสถานะกำลังใช้งานอยู่ + await page.click('id=field-select-status_1'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่ามีแต่สถานะใช้งานหรือไม่ + const statusActive = await page.isVisible('id=field-select-status_1'); + + console.log('มีเพียงสถานะการใช้งานเท่านั้น', statusActive); // เช็ค + + expect(statusActive).toBe(false); + + console.log('ตรวจสอบสถานะการใช้งานมีแต่สถานะกำลังใช้งานเท่านั้น'); + + // แสดงสถานะที่ไม่ใช้งาน + // คลิกเพื่อเปิด dropdown + await page.keyboard.press('Escape'); + await page.click('id=field-select-status'); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อแสดงสถานะกำลังไม่ใช้งาน + await page.click('id=field-select-status_2'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่ามีแต่สถานะไม่ใช้งานหรือไม่ + const statusInActive = await page.isVisible('id=field-select-status_1'); + + console.log('มีเพียงสถานะการใช้งานเท่านั้น', statusInActive); // เช็ค + + expect(statusActive).toBe(false); + + console.log('ตรวจสอบสถานะการใช้งานมีแต่สถานะที่ไม่ใช้งาน'); + + // แสดงสถานะทั้งหมด + // คลิกเพื่อเปิด dropdown + await page.keyboard.press('Escape'); + await page.click('id=field-select-status'); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อแสดงสถานะทั้งหมด + await page.click('id=field-select-status_0'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าแสดงทุกสถานะหรือไม่ + const statusAll = await page.isVisible('id=field-select-status_1'); + + console.log('สถานะทั้งหมด', statusAll); // เช็ค + + expect(statusActive).toBe(false); + + console.log('ตรวจสอบสถานะทั้งหมด'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } +}); + +test('ตรวจสอบการแสดงสถานะใช้งาน เปิด/ปิด พนักงานส่งเอกสาร', async () => { + try { + // คลิก Tab พนักงานส่งเอกสาร + await page.click("(//div[@role='tab'])[3]"); + + // แสดงสถานะที่ใช้งาน + // คลิกเพื่อเปิด dropdown + await page.click('id=field-select-status'); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อแสดงสถานะกำลังใช้งานอยู่ + await page.click('id=field-select-status_1'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่ามีแต่สถานะใช้งานหรือไม่ + const statusActive = await page.isVisible('id=field-select-status_1'); + + console.log('มีเพียงสถานะการใช้งานเท่านั้น', statusActive); // เช็ค + + expect(statusActive).toBe(false); + + console.log('ตรวจสอบสถานะการใช้งานมีแต่สถานะกำลังใช้งานเท่านั้น'); + + // แสดงสถานะที่ไม่ใช้งาน + // คลิกเพื่อเปิด dropdown + await page.keyboard.press('Escape'); + await page.click('id=field-select-status'); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อแสดงสถานะกำลังไม่ใช้งาน + await page.click('id=field-select-status_2'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่ามีแต่สถานะไม่ใช้งานหรือไม่ + const statusInActive = await page.isVisible('id=field-select-status_1'); + + console.log('มีเพียงสถานะการใช้งานเท่านั้น', statusInActive); // เช็ค + + expect(statusActive).toBe(false); + + console.log('ตรวจสอบสถานะการใช้งานมีแต่สถานะที่ไม่ใช้งาน'); + + // แสดงสถานะทั้งหมด + // คลิกเพื่อเปิด dropdown + await page.keyboard.press('Escape'); + await page.click('id=field-select-status'); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อแสดงสถานะทั้งหมด + await page.click('id=field-select-status_0'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าแสดงทุกสถานะหรือไม่ + const statusAll = await page.isVisible('id=field-select-status_1'); + + console.log('สถานะทั้งหมด', statusAll); // เช็ค + + expect(statusActive).toBe(false); + + console.log('ตรวจสอบสถานะทั้งหมด'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } +}); + +test('ตรวจสอบการแสดงสถานะใช้งาน เปิด/ปิด ตัวแทน', async () => { + try { + // คลิก Tab ตัวแทน + await page.click("(//div[@role='tab'])[4]"); + + // แสดงสถานะที่ใช้งาน + // คลิกเพื่อเปิด dropdown + await page.click('id=field-select-status'); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อแสดงสถานะกำลังใช้งานอยู่ + await page.click('id=field-select-status_1'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่ามีแต่สถานะใช้งานหรือไม่ + const statusActive = await page.isVisible('id=field-select-status_1'); + + console.log('มีเพียงสถานะการใช้งานเท่านั้น', statusActive); // เช็ค + + expect(statusActive).toBe(false); + + console.log('ตรวจสอบสถานะการใช้งานมีแต่สถานะกำลังใช้งานเท่านั้น'); + + // แสดงสถานะที่ไม่ใช้งาน + // คลิกเพื่อเปิด dropdown + await page.keyboard.press('Escape'); + await page.click('id=field-select-status'); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อแสดงสถานะกำลังไม่ใช้งาน + await page.click('id=field-select-status_2'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่ามีแต่สถานะไม่ใช้งานหรือไม่ + const statusInActive = await page.isVisible('id=field-select-status_1'); + + console.log('มีเพียงสถานะการใช้งานเท่านั้น', statusInActive); // เช็ค + + expect(statusActive).toBe(false); + + console.log('ตรวจสอบสถานะการใช้งานมีแต่สถานะที่ไม่ใช้งาน'); + + // แสดงสถานะทั้งหมด + // คลิกเพื่อเปิด dropdown + await page.keyboard.press('Escape'); + await page.click('id=field-select-status'); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อแสดงสถานะทั้งหมด + await page.click('id=field-select-status_0'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าแสดงทุกสถานะหรือไม่ + const statusAll = await page.isVisible('id=field-select-status_1'); + + console.log('สถานะทั้งหมด', statusAll); // เช็ค + + expect(statusActive).toBe(false); + + console.log('ตรวจสอบสถานะทั้งหมด'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } +}); + +test('ตรวจสอบการแสดงสถานะใช้งาน เปิด/ปิด เอเจนซี่', async () => { + try { + // คลิก Tab เอเจนซี่ + await page.click("(//div[@role='tab'])[5]"); + + // แสดงสถานะที่ใช้งาน + // คลิกเพื่อเปิด dropdown + await page.click('id=field-select-status'); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อแสดงสถานะกำลังใช้งานอยู่ + await page.click('id=field-select-status_1'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่ามีแต่สถานะใช้งานหรือไม่ + const statusActive = await page.isVisible('id=field-select-status_1'); + + console.log('มีเพียงสถานะการใช้งานเท่านั้น', statusActive); // เช็ค + + expect(statusActive).toBe(false); + + console.log('ตรวจสอบสถานะการใช้งานมีแต่สถานะกำลังใช้งานเท่านั้น'); + + // แสดงสถานะที่ไม่ใช้งาน + // คลิกเพื่อเปิด dropdown + await page.keyboard.press('Escape'); + await page.click('id=field-select-status'); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อแสดงสถานะกำลังไม่ใช้งาน + await page.click('id=field-select-status_2'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่ามีแต่สถานะไม่ใช้งานหรือไม่ + const statusInActive = await page.isVisible('id=field-select-status_1'); + + console.log('มีเพียงสถานะการใช้งานเท่านั้น', statusInActive); // เช็ค + + expect(statusActive).toBe(false); + + console.log('ตรวจสอบสถานะการใช้งานมีแต่สถานะที่ไม่ใช้งาน'); + + // แสดงสถานะทั้งหมด + // คลิกเพื่อเปิด dropdown + await page.keyboard.press('Escape'); + await page.click('id=field-select-status'); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อแสดงสถานะทั้งหมด + await page.click('id=field-select-status_0'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าแสดงทุกสถานะหรือไม่ + const statusAll = await page.isVisible('id=field-select-status_1'); + + console.log('สถานะทั้งหมด', statusAll); // เช็ค + + expect(statusActive).toBe(false); + + console.log('ตรวจสอบสถานะทั้งหมด'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } +}); diff --git a/tests/02-Admin-PersonnelManagement/JWS_PM_008_TypePersonnelFields.spec.ts b/tests/02-Admin-PersonnelManagement/JWS_PM_008_TypePersonnelFields.spec.ts new file mode 100644 index 00000000..91abf788 --- /dev/null +++ b/tests/02-Admin-PersonnelManagement/JWS_PM_008_TypePersonnelFields.spec.ts @@ -0,0 +1,2084 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +//---------------------------------Tab ทั้งหมด---------------------------------------- + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลลำดับ', async () => { + try { + // คลิกเมนูเพื่อเข้าหน้าจัดการบุคลากร + await page.click('id=menu-icon-personnel-management'); + + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_0'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_0'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_0'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลชื่อ-สกุล', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_1'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_1'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_1'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลประเภท', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_2'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_2'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_2'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลเบอร์โทรศัพท์', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_3'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_3'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_3'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลอายุ', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_4'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_4'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_4'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลอีเมล', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_5'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_5'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_5'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลสิทธิ์ผู้ใช้งาน', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_6'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_6'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_6'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); + await page.waitForTimeout(2000); +}); + +//---------------------------------Tab พนักงาน---------------------------------------- + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลลำดับ - พนักงาน', async () => { + try { + // คลิก Tab พนักงาน + await page.click("(//div[@role='tab'])[2]"); + + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_0'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_0'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_0'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลชื่อ-สกุล - พนักงาน', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_1'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_1'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_1'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลประเภท - พนักงาน', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_2'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_2'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_2'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลเบอร์โทรศัพท์ - พนักงาน', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_3'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_3'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_3'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลอายุ - พนักงาน', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_4'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_4'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_4'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลอีเมล - พนักงาน', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_5'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_5'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_5'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลสิทธิ์ผู้ใช้งาน - พนักงาน', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_6'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_6'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_6'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); + await page.waitForTimeout(2000); +}); + +//---------------------------------Tab พนักงานส่งเอกสาร---------------------------------------- + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลลำดับ - พนักงานส่งเอกสาร', async () => { + try { + // คลิก Tab พนักงาน + await page.click("(//div[@role='tab'])[3]"); + + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_0'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_0'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_0'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลชื่อ-สกุล - พนักงานส่งเอกสาร', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_1'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_1'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_1'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลประเภท - พนักงานส่งเอกสาร', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_2'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_2'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_2'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลเบอร์โทรศัพท์ - พนักงานส่งเอกสาร', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_3'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_3'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_3'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลอายุ - พนักงานส่งเอกสาร', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_4'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_4'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_4'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลอีเมล - พนักงานส่งเอกสาร', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_5'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_5'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_5'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลสิทธิ์ผู้ใช้งาน - พนักงานส่งเอกสาร', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_6'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_6'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_6'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); + await page.waitForTimeout(2000); +}); + +//---------------------------------Tab ตัวแทน---------------------------------------- + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลลำดับ - ตัวแทน', async () => { + try { + // คลิก Tab พนักงาน + await page.click("(//div[@role='tab'])[4]"); + + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_0'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_0'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_0'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลชื่อ-สกุล - ตัวแทน', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_1'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_1'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_1'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลประเภท - ตัวแทน', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_2'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_2'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_2'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลเบอร์โทรศัพท์ - ตัวแทน', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_3'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_3'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_3'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลอายุ - ตัวแทน', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_4'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_4'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_4'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลอีเมล - ตัวแทน', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_5'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_5'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_5'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลสิทธิ์ผู้ใช้งาน - ตัวแทน', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_6'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_6'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_6'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); + await page.waitForTimeout(2000); +}); + +//---------------------------------Tab เอเจนซี่---------------------------------------- + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลลำดับ - เอเจนซี่', async () => { + try { + // คลิก Tab พนักงาน + await page.click("(//div[@role='tab'])[5]"); + + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_0'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_0'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_0'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลชื่อ-สกุล - เอเจนซี่', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_1'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_1'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_1'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลประเภท - เอเจนซี่', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_2'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_2'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_2'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลเบอร์โทรศัพท์ - เอเจนซี่', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_3'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_3'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_3'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลอายุ - เอเจนซี่', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_4'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_4'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_4'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลอีเมล - เอเจนซี่', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_5'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_5'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_5'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); +}); + +test('ตรวจสอบการแสดงผลฟิลด์แสดงผลสิทธิ์ผู้ใช้งาน - เอเจนซี่', async () => { + try { + // คลิกเพื่อเปิด dropdown + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + + // คลิกเพื่อปิดคอลัมน์ที่ 1 + await page.click('id=select-field_6'); + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์ถูกซ่อน + const column1 = page.locator('id=select-field_6'); + const column1Cells = page.locator( + "//th[normalize-space(text())='ลำดับที่']", + ); + + const isColumn1Hidden = await column1.evaluate( + (el) => window.getComputedStyle(el).display === 'none', + ); + console.log('คอลัมน์ที่ 1 ซ่อนอยู่:', isColumn1Hidden); // เช็ค + + const areCellsHidden = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display === 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 ซ่อนอยู่:', areCellsHidden); // เช็ค + + expect(isColumn1Hidden).toBe(false); + expect(areCellsHidden).toBe(true); + + // คลิกอีกครั้งเพื่อเปิดคอลัมน์ที่ 1 + await page.keyboard.press('Escape'); + await page.click("(//input[@id='select-field'])[1]"); + await page.waitForTimeout(1000); // รอให้ dropdown เปิด + await page.click('id=select-field_6'); // คลิกเพื่อเปิดคอลัมน์ + await page.waitForTimeout(1000); // รอให้ UI อัปเดต + + // ตรวจสอบว่าคอลัมน์แสดงอยู่ + const isColumn1Visible = await column1.evaluate( + (el) => window.getComputedStyle(el).display !== 'none', + ); + console.log('คอลัมน์ที่ 1 แสดงอยู่:', isColumn1Visible); // เช็ค + + const areCellsVisible = await column1Cells.evaluateAll((cells) => + cells.every((cell) => window.getComputedStyle(cell).display !== 'none'), + ); + console.log('เซลล์ในคอลัมน์ที่ 1 แสดงอยู่:', areCellsVisible); // เช็ค + + expect(isColumn1Visible).toBe(true); + expect(areCellsVisible).toBe(true); + + console.log('ตรวจสอบการเปิด/ซ่อนคอลัมน์ในตารางสำเร็จ'); + } catch (error) { + console.error('เกิดข้อผิดพลาดในการทดสอบ:', error); + throw error; + } + await page.keyboard.press('Escape'); + await page.waitForTimeout(2000); +}); diff --git a/tests/03-Admin-ManageCustomer/JWS_MC_001_CreateNaturalperoson.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_001_CreateNaturalperoson.spec.ts new file mode 100644 index 00000000..fffb576d --- /dev/null +++ b/tests/03-Admin-ManageCustomer/JWS_MC_001_CreateNaturalperoson.spec.ts @@ -0,0 +1,118 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Create Natural Person', async () => { + await page.click('id=menu-icon-customer-management'); + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-natural-person'); + await page.fill("(//input[@id='input-employer-id'])[3]", 'ปิง'); + await page.fill("(//input[@id='input-tax-no'])[3]", '1242822482204'); + await page.fill("(//input[@id='input-customer-name'])[3]", 'โคโม่'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Como'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//div[@role='option']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@id='input-start-date'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Second', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-natural-person'); + await page.fill("(//input[@id='input-employer-id'])[3]", 'วัง'); + await page.fill("(//input[@id='input-tax-no'])[3]", 'จคภ/คค/ุ//'); + await page.fill("(//input[@id='input-customer-name'])[3]", 'โคโม่'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Como'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//div[@role='option']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@id='input-start-date'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); diff --git a/tests/03-Admin-ManageCustomer/JWS_MC_002_CreateNaturalperosonfail.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_002_CreateNaturalperosonfail.spec.ts new file mode 100644 index 00000000..ed7f59f7 --- /dev/null +++ b/tests/03-Admin-ManageCustomer/JWS_MC_002_CreateNaturalperosonfail.spec.ts @@ -0,0 +1,249 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Create Natural Person No input Data', async () => { + await page.click('id=menu-icon-customer-management'); + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-natural-person'); + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); + await page.click('id=cancelBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person No Input Employee name', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-natural-person'); + await page.fill("(//input[@id='input-employer-id'])[3]", ''); + await page.fill("(//input[@id='input-tax-no'])[3]", '1242822482204'); + await page.fill("(//input[@id='input-customer-name'])[3]", 'โคโม่'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Como'); + await page.fill("(//input[@id='input-customerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//div[@role='option']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person No Input Tax No', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-natural-person'); + await page.fill("(//input[@id='input-employer-id'])[3]", 'ปิง'); + await page.fill("(//input[@id='input-tax-no'])[3]", ''); + await page.fill("(//input[@id='input-customer-name'])[3]", 'โคโม่'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Como'); + await page.fill("(//input[@id='input-customerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//div[@role='option']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.click('id=cancelBtn'); + + await page.waitForTimeout(2000); +}); + +test('Create Natural Person No Input Customer Name TH', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-natural-person'); + await page.fill("(//input[@id='input-employer-id'])[3]", 'ปิง'); + await page.fill("(//input[@id='input-tax-no'])[3]", '1242822482204'); + await page.fill("(//input[@id='input-customer-name'])[3]", ''); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Como'); + await page.fill("(//input[@id='input-customerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//div[@role='option']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person No Input Customer Name EN', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-natural-person'); + await page.fill("(//input[@id='input-employer-id'])[3]", 'ปิง'); + await page.fill("(//input[@id='input-tax-no'])[3]", '1242822482204'); + await page.fill("(//input[@id='input-customer-name'])[3]", 'โคโม่'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", ''); + await page.fill("(//input[@id='input-customerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//div[@role='option']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person No Input Customername', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-natural-person'); + await page.fill("(//input[@id='input-employer-id'])[3]", 'ปิง'); + await page.fill("(//input[@id='input-tax-no'])[3]", '1242822482204'); + await page.fill("(//input[@id='input-customer-name'])[3]", 'โคโม่'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Como'); + await page.fill("(//input[@id='input-customerName'])[3]", ''); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//div[@role='option']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person No Input Address TH', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-natural-person'); + await page.fill("(//input[@id='input-employer-id'])[3]", 'ปิง'); + await page.fill("(//input[@id='input-tax-no'])[3]", '1242822482204'); + await page.fill("(//input[@id='input-customer-name'])[3]", 'โคโม่'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Como'); + await page.fill("(//input[@id='input-customerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-address-0'])[3]", ''); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//div[@role='option']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); + await page.click('id=cancelBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Select Province', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-natural-person'); + await page.fill("(//input[@id='input-employer-id'])[3]", 'ปิง'); + await page.fill("(//input[@id='input-tax-no'])[3]", '1242822482204'); + await page.fill("(//input[@id='input-customer-name'])[3]", 'โคโม่'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Como'); + await page.fill("(//input[@id='input-customerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); + await page.click('id=cancelBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Select District', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-natural-person'); + await page.fill("(//input[@id='input-employer-id'])[3]", 'ปิง'); + await page.fill("(//input[@id='input-tax-no'])[3]", '1242822482204'); + await page.fill("(//input[@id='input-customer-name'])[3]", 'โคโม่'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Como'); + await page.fill("(//input[@id='input-customerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//div[@role='option']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); + await page.click('id=cancelBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Select Sub District', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-natural-person'); + await page.fill("(//input[@id='input-employer-id'])[3]", 'ปิง'); + await page.fill("(//input[@id='input-tax-no'])[3]", '1242822482204'); + await page.fill("(//input[@id='input-customer-name'])[3]", 'โคโม่'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Como'); + await page.fill("(//input[@id='input-customerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//div[@role='option']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); + await page.click('id=cancelBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Input Address ENG', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-natural-person'); + await page.fill("(//input[@id='input-employer-id'])[3]", 'ปิง'); + await page.fill("(//input[@id='input-tax-no'])[3]", '1242822482204'); + await page.fill("(//input[@id='input-customer-name'])[3]", 'โคโม่'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Como'); + await page.fill("(//input[@id='input-customerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//div[@role='option']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", ''); + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); + await page.click('id=cancelBtn'); + await page.waitForTimeout(2000); +}); diff --git a/tests/02-Admin-PersonnelManagement/JWS_PM_002_ViewDetail.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_003_DetailNaturalperson.spec.ts similarity index 68% rename from tests/02-Admin-PersonnelManagement/JWS_PM_002_ViewDetail.spec.ts rename to tests/03-Admin-ManageCustomer/JWS_MC_003_DetailNaturalperson.spec.ts index 7ca45cf6..539eb2ca 100644 --- a/tests/02-Admin-PersonnelManagement/JWS_PM_002_ViewDetail.spec.ts +++ b/tests/03-Admin-ManageCustomer/JWS_MC_003_DetailNaturalperson.spec.ts @@ -24,9 +24,10 @@ test('Login', async () => { // await page.click('id=acceptBtn'); }); -test('View Deatil Personnel', async () => { - await page.click('id=menu-icon-personnel-management'); - await page.click("(//div[@class='full-width text-right']//button)[1]"); - await page.click("(//div[@class='q-focus-helper']/following-sibling::i)[1]"); - await page.waitForTimeout(4000); +test('Selete Filter Manage Customer Active', async () => { + await page.click('id=menu-icon-customer-management'); + await page.click('id=btn-eye-โคโม่'); + await page.waitForTimeout(2000); + await page.click("(//button[@id='closeDialog'])[1]"); + await page.waitForTimeout(2000); }); diff --git a/tests/03-Admin-ManageCustomer/JWS_MC_004_EditNaturalperson.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_004_EditNaturalperson.spec.ts new file mode 100644 index 00000000..4e32a8a8 --- /dev/null +++ b/tests/03-Admin-ManageCustomer/JWS_MC_004_EditNaturalperson.spec.ts @@ -0,0 +1,41 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Edit Naturalperson', async () => { + // รออัพเดท PATH + await page.click('id=menu-icon-customer-management'); + await page.click("//button[@id='btn-dots-PERS000001']"); + await page.click('id=view-detail-btn-undefined-edit'); + await page.click( + "//div[contains(@class,'q-field__append q-field__marginal')]/following-sibling::div[1]", + ); + await page.click("//span[text()='บางรัก']"); + await page.fill("(//input[@id='input-employer-id'])[1]", 'หลินปิง'); + await page.fill("(//input[@id='input-customerName'])[1]", 'บางรัก'); + await page.fill("(//input[@id='input-customerEnglishName'])[1]", 'Bangrak'); + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); diff --git a/tests/03-Admin-ManageCustomer/JWS_MC_005_DeleteNaturalperson.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_005_DeleteNaturalperson.spec.ts new file mode 100644 index 00000000..ba10c85b --- /dev/null +++ b/tests/03-Admin-ManageCustomer/JWS_MC_005_DeleteNaturalperson.spec.ts @@ -0,0 +1,34 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Delete Naturalperson', async () => { + // รออัพเดท PATH + await page.click('id=menu-icon-customer-management'); + await page.click("//button[@id='btn-dots-PERS000002']"); + await page.click('id=view-detail-btn-undefined-delete'); + await page.click('id=btn-ok-dialog'); + await page.waitForTimeout(2000); +}); diff --git a/tests/03-Admin-ManageCustomer/JWS_MC_006_StatusNaturalperson.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_006_StatusNaturalperson.spec.ts new file mode 100644 index 00000000..b9ada759 --- /dev/null +++ b/tests/03-Admin-ManageCustomer/JWS_MC_006_StatusNaturalperson.spec.ts @@ -0,0 +1,38 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Status On Natural Person', async () => { + await page.click('id=menu-icon-customer-management'); + await page.click("//button[@id='btn-dots-PERS000002']"); + await page.click('id=view-detail-btn-undefined-status'); + await page.waitForTimeout(2000); +}); + +test('Status Off Natural Person', async () => { + await page.click('id=btn-dots-โคโม่'); + await page.click('id=view-detail-btn-undefined-status'); + await page.waitForTimeout(2000); +}); diff --git a/tests/03-Admin-ManageCustomer/JWS_MC_007_CreateLegalentitly.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_007_CreateLegalentitly.spec.ts new file mode 100644 index 00000000..3d1efe90 --- /dev/null +++ b/tests/03-Admin-ManageCustomer/JWS_MC_007_CreateLegalentitly.spec.ts @@ -0,0 +1,132 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Create Legalentitly Person', async () => { + await page.click('id=menu-icon-customer-management'); + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("//span[text()='บางรัก']"); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลอย'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Loi'); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Bangrak'); + await page.fill("(//input[@id='input-customerName'])[3]", 'บางรัก'); + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.waitForTimeout(2000); + await page.click("//div[@role='option']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.waitForTimeout(2000); + await page.click("//div[@role='option']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Legalentitly Person Second', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลาภ'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Lab'); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.waitForTimeout(2000); + await page.click("//div[@role='option']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.waitForTimeout(2000); + await page.click("//div[@role='option']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); diff --git a/tests/03-Admin-ManageCustomer/JWS_MC_008_CreateLegalentitlyfail.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_008_CreateLegalentitlyfail.spec.ts new file mode 100644 index 00000000..97dff87e --- /dev/null +++ b/tests/03-Admin-ManageCustomer/JWS_MC_008_CreateLegalentitlyfail.spec.ts @@ -0,0 +1,1226 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Create Natural Person Not Input Data', async () => { + await page.click('id=menu-icon-customer-management'); + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); + await page.click('id=cancelBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Input Name TH', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.fill("(//input[@id='input-customer-name'])[3]", ''); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Loi'); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.click("//span[text()='สารภี']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.click("//span[text()='ท่าวังตาล']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Input Name ENG', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลอย'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", ''); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.click("//span[text()='สารภี']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.click("//span[text()='ท่าวังตาล']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Input Name Company', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลอย'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Loi'); + await page.fill("(//input[@id='input-owner-name'])[3]", ''); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.click("//span[text()='สารภี']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.click("//span[text()='ท่าวังตาล']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Input Customername ENG ', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลอย'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Loi'); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", ''); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.click("//span[text()='สารภี']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.click("//span[text()='ท่าวังตาล']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Input Customername TH', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลอย'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Loi'); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-customerName'])[3]", ''); + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.click("//span[text()='สารภี']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.click("//span[text()='ท่าวังตาล']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Input Tax No', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลอย'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Loi'); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + + await page.fill("(//input[@id='input-taxNo'])[3]", ''); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.click("//span[text()='สารภี']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.click("//span[text()='ท่าวังตาล']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); + await page.click('id=cancelBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Input Registername', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลอย'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Loi'); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", ''); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.click("//span[text()='สารภี']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.click("//span[text()='ท่าวังตาล']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Input Authorizedcapital', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลอย'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Loi'); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", ''); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.click("//span[text()='สารภี']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.click("//span[text()='ท่าวังตาล']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Select Date', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลอย'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Loi'); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.click("//span[text()='สารภี']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.click("//span[text()='ท่าวังตาล']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Input Address TH', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลอย'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Loi'); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", ''); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.click("//span[text()='สารภี']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.click("//span[text()='ท่าวังตาล']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); + await page.click('id=cancelBtn'); +}); + +test('Create Natural Person Not Select Province', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลอย'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Loi'); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); + await page.click('id=cancelBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Select District', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลอย'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Loi'); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); + await page.click('id=cancelBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Select Subdistrict', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลอย'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Loi'); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.click("//span[text()='สารภี']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); + await page.click('id=cancelBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Input Address ENG', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลอย'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Loi'); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.click("//span[text()='สารภี']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.click("//span[text()='ท่าวังตาล']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", ''); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); + await page.click('id=cancelBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Input Employee Office', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลอย'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Loi'); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.click("//span[text()='สารภี']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.click("//span[text()='ท่าวังตาล']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Select Business Type', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลอย'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Loi'); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.click("//span[text()='สารภี']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.click("//span[text()='ท่าวังตาล']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Select Job Position', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลอย'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Loi'); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.click("//span[text()='สารภี']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.click("//span[text()='ท่าวังตาล']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Input Job Discription', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลอย'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Loi'); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.click("//span[text()='สารภี']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.click("//span[text()='ท่าวังตาล']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Select Paydate', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลอย'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Loi'); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.click("//span[text()='สารภี']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.click("//span[text()='ท่าวังตาล']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Input Sales Person', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลอย'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Loi'); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.click("//span[text()='สารภี']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.click("//span[text()='ท่าวังตาล']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", ''); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Input Email', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลอย'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Loi'); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.click("//span[text()='สารภี']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.click("//span[text()='ท่าวังตาล']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", ''); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Input Telephone Number', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลอย'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Loi'); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.click("//span[text()='สารภี']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.click("//span[text()='ท่าวังตาล']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", ''); + await page.setInputFiles( + "(//input[contains(@class,'q-field__input fit')])[3]", + '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + ); // UploadFile + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Natural Person Not Input File', async () => { + await page.click("(//div[@id='btn-add'])[1]"); + await page.click('id=add-customer-legal-entity'); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.click("(//div[@id='input-source-nationality'])[3]"); + await page.fill("(//input[@id='input-customer-name'])[3]", 'ลอย'); + await page.fill("(//input[@id='input-customer-name-en'])[3]", 'Loi'); + await page.fill("(//input[@id='input-owner-name'])[3]", 'ปิงปิง'); + await page.fill("(//input[@id='input-customerEnglishName'])[3]", 'Silom'); + await page.fill("(//input[@id='input-customerName'])[3]", 'สีลม'); + + await page.fill("(//input[@id='input-taxNo'])[3]", '1284262822028'); + await page.fill("(//input[@id='input-registerName'])[3]", 'ปองพล กันธะณะ'); + await page.fill("(//input[@id='input-authorizedCapital'])[3]", '20000000'); + await page.click("(//input[@aria-label='จดทะเบียนเมื่อ'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2560']"); + await page.click("(//div[text()='30'])[2]"); + await page.fill("(//input[@id='input-address-0'])[3]", '20/02'); + await page.click("(//div[@id='select-province-0'])[3]"); + await page.click("//span[text()='เชียงใหม่']"); + await page.click("(//div[@id='select-district-0'])[3]"); + await page.click("//span[text()='สารภี']"); + await page.click("(//div[@id='select-sub-district-0'])[3]"); + await page.click("//span[text()='ท่าวังตาล']"); + await page.fill("(//input[@id='input-address-en-0'])[3]", '20/02'); + await page.fill( + "(//input[@id='input-employment-office'])[3]", + 'กรุงเทพมหานคร', + ); + await page.click("(//div[@id='select-business-type'])[3]"); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='select-job-position'])[3]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + "(//input[@id='input-job-description'])[3]", + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click("(//input[@aria-label='วันที่จ่ายค่าแรง'])[3]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-sales-person'])[3]", 'พนักงานขาย'); + await page.fill("(//input[@id='input-mail'])[3]", 'jws@local.com'); + await page.fill("(//input[@id='input-telephone'])[3]", '0864228464'); + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); diff --git a/tests/02-Admin-PersonnelManagement/JWS_PM_003_EditPersonnel.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_009_DetailLegalentitly.spec.ts similarity index 73% rename from tests/02-Admin-PersonnelManagement/JWS_PM_003_EditPersonnel.spec.ts rename to tests/03-Admin-ManageCustomer/JWS_MC_009_DetailLegalentitly.spec.ts index 69375f92..111813fb 100644 --- a/tests/02-Admin-PersonnelManagement/JWS_PM_003_EditPersonnel.spec.ts +++ b/tests/03-Admin-ManageCustomer/JWS_MC_009_DetailLegalentitly.spec.ts @@ -24,9 +24,10 @@ test('Login', async () => { // await page.click('id=acceptBtn'); }); -test('Edit Personnel', async () => { - await page.click('id=menu-icon-personnel-management'); - await page.click("(//div[@class='full-width text-right']//button)[1]"); - await page.click("(//div[@class='q-focus-helper']/following-sibling::i)[2]"); +test('View Detail Legalentitly', async () => { + await page.click('id=menu-icon-customer-management'); + await page.click("//button[@id='btn-dots-CORP000002']"); + + await page.click('id=view-detail-btn-undefined-view'); await page.waitForTimeout(2000); }); diff --git a/tests/03-Admin-ManageCustomer/JWS_MC_010_EditLegalentitly.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_010_EditLegalentitly.spec.ts new file mode 100644 index 00000000..2dc6b93d --- /dev/null +++ b/tests/03-Admin-ManageCustomer/JWS_MC_010_EditLegalentitly.spec.ts @@ -0,0 +1,37 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Edit Legalentitly ', async () => { + await page.click('id=menu-icon-customer-management'); + await page.click("//button[@id='btn-dots-CORP000002']"); + await page.click('id=view-detail-btn-undefined-edit'); + await page.click("(//div[@id='input-source-nationality'])[1]"); + await page.click("//span[text()='บางรัก']"); + await page.fill("(//input[@id='input-customerEnglishName'])[1]", 'Bangrak'); + await page.fill("(//input[@id='input-customerName'])[1]", 'บางรัก'); + await page.click('id=submitBtn'); + await page.waitForTimeout(2000); +}); diff --git a/tests/03-Admin-ManageCustomer/JWS_MC_011_DeleteLegalentitly.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_011_DeleteLegalentitly.spec.ts new file mode 100644 index 00000000..ec13917a --- /dev/null +++ b/tests/03-Admin-ManageCustomer/JWS_MC_011_DeleteLegalentitly.spec.ts @@ -0,0 +1,35 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Delete Legalentitly', async () => { + // รออัพเดท PATH + await page.click('id=menu-icon-customer-management'); + await page.click("//button[@id='btn-dots-CORP000002']"); + + await page.click('id=view-detail-btn-undefined-delete'); + await page.click('id=btn-ok-dialog'); + await page.waitForTimeout(2000); +}); diff --git a/tests/03-Admin-ManageCustomer/JWS_MC_012_StatusLegalentitly.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_012_StatusLegalentitly.spec.ts new file mode 100644 index 00000000..1803675f --- /dev/null +++ b/tests/03-Admin-ManageCustomer/JWS_MC_012_StatusLegalentitly.spec.ts @@ -0,0 +1,39 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Status Off Legalentitly', async () => { + await page.click('id=menu-icon-customer-management'); + await page.click("//button[@id='btn-dots-CORP000002']"); + await page.click('id=view-detail-btn-undefined-status'); + await page.waitForTimeout(2000); +}); + +test('Status On Legalentitly', async () => { + await page.click("//button[@id='btn-dots-CORP000002']"); + await page.waitForTimeout(2000); + await page.click('id=view-detail-btn-undefined-status'); + await page.waitForTimeout(2000); +}); diff --git a/tests/01-Admin-BranchManagement/JWS_BM_009_SearchBranchmanagement.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_013_DropdownEmployertype.spec.ts similarity index 56% rename from tests/01-Admin-BranchManagement/JWS_BM_009_SearchBranchmanagement.spec.ts rename to tests/03-Admin-ManageCustomer/JWS_MC_013_DropdownEmployertype.spec.ts index de5ee522..ed99ea8d 100644 --- a/tests/01-Admin-BranchManagement/JWS_BM_009_SearchBranchmanagement.spec.ts +++ b/tests/03-Admin-ManageCustomer/JWS_MC_013_DropdownEmployertype.spec.ts @@ -1,5 +1,6 @@ import { test, expect, Page } from '@playwright/test'; import { strictEqual } from 'assert'; +import { escape } from 'querystring'; let page: Page; @@ -24,26 +25,33 @@ test('Login', async () => { // await page.click('id=acceptBtn'); }); -test('Search Branch Management', async () => { - await page.click('id=menu-icon-branch-management'); - await page.fill('id=input-Search', 'สีลม'); +test('Select Dropdown Employer Type Off', async () => { + await page.click('id=menu-icon-customer-management'); + await page.click('id=select-field'); + await page.click('id=select-field_0'); await page.waitForTimeout(2000); - await page.fill('id=input-Search', 'สีลม1'); + await page.click('id=select-field_1'); await page.waitForTimeout(2000); - await page.fill('id=input-Search', 'สี'); + await page.click('id=select-field_2'); await page.waitForTimeout(2000); - await page.fill('id=input-Search', '1'); + await page.click('id=select-field_3'); await page.waitForTimeout(2000); - await page.fill('id=input-Search', '20/02'); + await page.click('id=select-field_4'); await page.waitForTimeout(2000); - await page.fill('id=input-Search', 'เชียงใหม่'); - await page.waitForTimeout(2000); - await page.fill('id=input-Search', 'เมือง'); - await page.waitForTimeout(2000); - await page.fill('id=input-Search', 'ช้างเผือก'); - await page.waitForTimeout(2000); - await page.fill('id=input-Search', 'ดำเนินการอยู่'); - await page.waitForTimeout(2000); - await page.fill('id=input-Search', 'ปิดดำเนินการ'); + await page.keyboard.press('Escape'); + await page.waitForTimeout(2000); +}); + +test('Select Dropdown Employer Type on', async () => { + await page.click('id=select-field'); + await page.click('id=select-field_0'); + await page.waitForTimeout(2000); + await page.click('id=select-field_1'); + await page.waitForTimeout(2000); + await page.click('id=select-field_2'); + await page.waitForTimeout(2000); + await page.click('id=select-field_3'); + await page.waitForTimeout(2000); + await page.click('id=select-field_4'); await page.waitForTimeout(2000); }); diff --git a/tests/03-Admin-ManageCustomer/JWS_MC_014_SearchManageCustomer.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_014_SearchManageCustomer.spec.ts new file mode 100644 index 00000000..5546521e --- /dev/null +++ b/tests/03-Admin-ManageCustomer/JWS_MC_014_SearchManageCustomer.spec.ts @@ -0,0 +1,43 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Selete Filter Manage Customer Active', async () => { + await page.click('id=menu-icon-customer-management'); + await page.fill('id=input-search', 'โค'); + await page.waitForTimeout(2000); + await page.fill('id=input-search', 'โคโม่'); + await page.waitForTimeout(2000); + await page.fill('id=input-search', 'นิติบุคคล'); + await page.waitForTimeout(2000); + await page.fill('id=input-search', 'Como'); + await page.waitForTimeout(2000); + await page.fill('id=input-search', 'Co'); + await page.waitForTimeout(2000); + await page.fill('id=input-search', 'Lab'); + await page.waitForTimeout(2000); + await page.fill('id=input-search', 'L'); + await page.waitForTimeout(2000); +}); diff --git a/tests/02-Admin-PersonnelManagement/JWS_PM_006_FilterStatusPersonnel.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_015_FilterManageStatusCustomer.spec.ts similarity index 61% rename from tests/02-Admin-PersonnelManagement/JWS_PM_006_FilterStatusPersonnel.spec.ts rename to tests/03-Admin-ManageCustomer/JWS_MC_015_FilterManageStatusCustomer.spec.ts index 4bbe1f67..d194c89b 100644 --- a/tests/02-Admin-PersonnelManagement/JWS_PM_006_FilterStatusPersonnel.spec.ts +++ b/tests/03-Admin-ManageCustomer/JWS_MC_015_FilterManageStatusCustomer.spec.ts @@ -24,21 +24,21 @@ test('Login', async () => { // await page.click('id=acceptBtn'); }); -test('Select Filter Status Active Personnel', async () => { - await page.click('id=menu-icon-personnel-management'); - await page.click('id=btn-filter'); - await page.click('id=btn-filter-active'); +test('Selete Filter Manage Customer Active', async () => { + await page.click('id=menu-icon-customer-management'); + await page.click('id=select-status'); + await page.click('id=select-status_1'); await page.waitForTimeout(2000); }); -test('Select Filter Status InActive Personnel', async () => { - await page.click('id=btn-filter'); - await page.click('id=btn-filter-inactive'); +test('Selete Filter Manage Customer Inative', async () => { + await page.click('id=select-status'); + await page.click('id=select-status_2'); await page.waitForTimeout(2000); }); -test('Select Filter Status All Personnel', async () => { - await page.click('id=btn-filter'); - await page.click('id=btn-filter-all'); +test('Selete Filter Manage Customer All', async () => { + await page.click('id=select-status'); + await page.click('id=select-status_0'); await page.waitForTimeout(2000); }); diff --git a/tests/03-Admin-ManageCustomer/JWS_MC_016_CreateEmployee.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_016_CreateEmployee.spec.ts new file mode 100644 index 00000000..88e5d3cd --- /dev/null +++ b/tests/03-Admin-ManageCustomer/JWS_MC_016_CreateEmployee.spec.ts @@ -0,0 +1,98 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Select Employee Tab', async () => { + await page.click('id=menu-icon-customer-management'); + await page.click('id=tab-employee'); + await page.click('id=btn-add'); + await page.click('id=add-employee'); + await page.waitForTimeout(2000); +}); + +test('Create Employee', async () => { + await page.click("(//input[@id='select-employer-branch'])[2]"); + await page.click('id=select-employer-branch_0'); + await page.fill("(//input[@id='input-nrcNo'])[2]", '6282282246226'); + await page.fill("(//input[@id='input-first-name'])[2]", 'ปองพล'); + await page.fill("(//input[@id='input-last-name'])[2]", 'กันธะณะ'); + await page.fill("(//input[@id='input-first-name-en'])[2]", 'Pongpon'); + await page.fill("(//input[@id='input-last-name-en'])[2]", 'Kuntana'); + await page.click("(//input[@id='input-birth-date'])[2]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2536']"); + await page.click("//div[text()='8']"); + await page.click("(//div[@id='select-gender'])[2]"); + await page.click("//span[text()='หญิง']"); + await page.click("(//div[@id='select-nationality'])[2]"); + await page.waitForTimeout(2000); + await page.click("(//div[@role='option'])[1]"); + await page.waitForTimeout(2000); +}); + +test('Create Detail OCR ', async () => { + await page.click("(//div[@id='select-passport-type'])[2]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill("(//input[@id='input-passport-no'])[2]", 'TH2862242226262'); + await page.fill("(//input[@id='input-passport-ref'])[2]", '2042022022426'); + await page.fill("(//input[@id='input-passport-place'])[2]", 'Bangkok'); + await page.click("(//div[@id='select-passport-country'])[2]"); + await page.waitForTimeout(2000); + await page.click("(//div[@role='option'])[1]"); + await page.click("(//input[@aria-label='วันที่ออกหนังสือเดินทาง'])[2]"); + await page.click("(//div[text()='2'])[1]"); + await page.click("(//input[@aria-label='วันหมดอายุหนังสือเดินทาง'])[2]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2574']"); + await page.click("//div[text()='8']"); + await page.waitForTimeout(2000); +}); + +test('Create VISA OCR', async () => { + await page.click("(//div[@id='select-visa-type'])[2]"); + await page.waitForTimeout(2000); + await page.click("(//div[@role='option'])[1]"); + await page.fill("(//input[@id='input-visa-no'])[2]", '200222'); + await page.click("(//input[@aria-label='ออกให้วันที่'])[2]"); + await page.click("//div[text()='18']"); + await page.click("(//input[@aria-label='ใช้ได้ถึงวันที่'])[2]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2568']"); + await page.click("//div[text()='8']"); + await page.fill( + "(//input[@id='input-visa-place'])[2]", + 'กรมตรวจคนเข้าเมืองน่าน', + ); + await page.click("(//input[@aria-label='ให้อยู่ในราชอาณาจักรถึงวันที่'])[2]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2568']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-tm6'])[2]", '204422002'); + await page.click("(//input[@aria-label='วันที่เดินทางเข้ามาในประเทศ'])[2]"); + await page.click("//div[text()='18']"); + await page.click('id=submitBtn'); + await page.click('id=btn-ok-dialog'); + await page.waitForTimeout(2000); +}); diff --git a/tests/03-Admin-ManageCustomer/JWS_MC_017_CreateEmployeeFail.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_017_CreateEmployeeFail.spec.ts new file mode 100644 index 00000000..d5ac5484 --- /dev/null +++ b/tests/03-Admin-ManageCustomer/JWS_MC_017_CreateEmployeeFail.spec.ts @@ -0,0 +1,297 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Select Employee Tab', async () => { + await page.click('id=menu-icon-customer-management'); + await page.waitForTimeout(2000); +}); + +test('Create Employee Not Input Data', async () => { + await page.click('id=tab-employee'); + await page.click('id=btn-add'); + await page.click('id=add-employee'); + await page.click('id=submitBtn'); + await page.click('id=cancelBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Employee Not Select Employee Code ', async () => { + await page.click('id=btn-add'); + await page.click('id=add-employee'); + await page.fill("(//input[@id='input-nrcNo'])[2]", '6282282246226'); + await page.fill("(//input[@id='input-first-name'])[2]", 'ปองพล'); + await page.fill("(//input[@id='input-last-name'])[2]", 'กันธะณะ'); + await page.fill("(//input[@id='input-first-name-en'])[2]", 'Pongpon'); + await page.fill("(//input[@id='input-last-name-en'])[2]", 'Kuntana'); + await page.click("(//input[@id='input-birth-date'])[2]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2536']"); + await page.click("//div[text()='8']"); + await page.click("(//div[@id='select-gender'])[2]"); + await page.click("//span[text()='หญิง']"); + await page.click("(//div[@id='select-nationality'])[2]"); + await page.waitForTimeout(2000); + await page.click("(//div[@role='option'])[1]"); + await page.waitForTimeout(2000); + await page.click("(//div[@id='select-passport-type'])[2]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill("(//input[@id='input-passport-no'])[2]", 'TH2862242226262'); + await page.fill("(//input[@id='input-passport-ref'])[2]", '2042022022426'); + await page.fill("(//input[@id='input-passport-place'])[2]", 'Bangkok'); + await page.click("(//div[@id='select-passport-country'])[2]"); + await page.waitForTimeout(2000); + await page.click("(//div[@role='option'])[1]"); + await page.click("(//input[@aria-label='วันที่ออกหนังสือเดินทาง'])[2]"); + await page.click("(//div[text()='2'])[1]"); + await page.click("(//input[@aria-label='วันหมดอายุหนังสือเดินทาง'])[2]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2574']"); + await page.click("//div[text()='8']"); + await page.waitForTimeout(2000); + await page.click("(//div[@id='select-visa-type'])[2]"); + await page.waitForTimeout(2000); + await page.click("(//div[@role='option'])[1]"); + await page.fill("(//input[@id='input-visa-no'])[2]", '200222'); + await page.click("(//input[@aria-label='ออกให้วันที่'])[2]"); + await page.click("//div[text()='18']"); + await page.click("(//input[@aria-label='ใช้ได้ถึงวันที่'])[2]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2568']"); + await page.click("//div[text()='8']"); + await page.fill( + "(//input[@id='input-visa-place'])[2]", + 'กรมตรวจคนเข้าเมืองน่าน', + ); + await page.click("(//input[@aria-label='ให้อยู่ในราชอาณาจักรถึงวันที่'])[2]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2568']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-tm6'])[2]", '204422002'); + await page.click("(//input[@aria-label='วันที่เดินทางเข้ามาในประเทศ'])[2]"); + await page.click("//div[text()='18']"); + await page.click('id=submitBtn'); + await page.click('id=cancelBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Employee Not Input Personal Information ', async () => { + await page.click('id=btn-add'); + await page.click('id=add-employee'); + await page.click("(//input[@id='select-employer-branch'])[2]"); + await page.click('id=select-employer-branch_0'); + await page.fill("(//input[@id='input-nrcNo'])[2]", '6282282246226'); + + await page.click("(//div[@id='select-passport-type'])[2]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill("(//input[@id='input-passport-no'])[2]", 'TH2862242226262'); + await page.fill("(//input[@id='input-passport-ref'])[2]", '2042022022426'); + await page.fill("(//input[@id='input-passport-place'])[2]", 'Bangkok'); + await page.click("(//div[@id='select-passport-country'])[2]"); + await page.waitForTimeout(2000); + await page.click("(//div[@role='option'])[1]"); + await page.click("(//input[@aria-label='วันที่ออกหนังสือเดินทาง'])[2]"); + await page.click("(//div[text()='2'])[1]"); + await page.click("(//input[@aria-label='วันหมดอายุหนังสือเดินทาง'])[2]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2574']"); + await page.click("//div[text()='8']"); + await page.waitForTimeout(2000); + + await page.click("(//div[@id='select-visa-type'])[2]"); + await page.waitForTimeout(2000); + await page.click("(//div[@role='option'])[1]"); + await page.fill("(//input[@id='input-visa-no'])[2]", '200222'); + await page.click("(//input[@aria-label='ออกให้วันที่'])[2]"); + await page.click("//div[text()='18']"); + await page.click("(//input[@aria-label='ใช้ได้ถึงวันที่'])[2]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2568']"); + await page.click("//div[text()='8']"); + await page.fill( + "(//input[@id='input-visa-place'])[2]", + 'กรมตรวจคนเข้าเมืองน่าน', + ); + await page.click("(//input[@aria-label='ให้อยู่ในราชอาณาจักรถึงวันที่'])[2]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2568']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-tm6'])[2]", '204422002'); + await page.click("(//input[@aria-label='วันที่เดินทางเข้ามาในประเทศ'])[2]"); + await page.click("//div[text()='18']"); + await page.click('id=submitBtn'); + await page.click('id=btn-ok-dialog'); + await page.click('id=submitBtn'); + await page.click('id=cancelBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Employee Not Input Personal Address ', async () => { + await page.click('id=btn-add'); + await page.click('id=add-employee'); + + await page.click("(//input[@id='select-employer-branch'])[2]"); + await page.click('id=select-employer-branch_0'); + await page.fill("(//input[@id='input-nrcNo'])[2]", '6282282246226'); + await page.fill("(//input[@id='input-first-name'])[2]", 'ปองพล'); + await page.fill("(//input[@id='input-last-name'])[2]", 'กันธะณะ'); + await page.fill("(//input[@id='input-first-name-en'])[2]", 'Pongpon'); + await page.fill("(//input[@id='input-last-name-en'])[2]", 'Kuntana'); + await page.click("(//input[@id='input-birth-date'])[2]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2536']"); + await page.click("//div[text()='8']"); + await page.click("(//div[@id='select-gender'])[2]"); + await page.click("//span[text()='หญิง']"); + await page.click("(//div[@id='select-nationality'])[2]"); + await page.waitForTimeout(2000); + await page.click("(//div[@role='option'])[1]"); + await page.waitForTimeout(2000); + + await page.click("(//div[@id='select-passport-type'])[2]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill("(//input[@id='input-passport-no'])[2]", 'TH2862242226262'); + await page.fill("(//input[@id='input-passport-ref'])[2]", '2042022022426'); + await page.fill("(//input[@id='input-passport-place'])[2]", 'Bangkok'); + await page.click("(//div[@id='select-passport-country'])[2]"); + await page.waitForTimeout(2000); + await page.click("(//div[@role='option'])[1]"); + await page.click("(//input[@aria-label='วันที่ออกหนังสือเดินทาง'])[2]"); + await page.click("(//div[text()='2'])[1]"); + await page.click("(//input[@aria-label='วันหมดอายุหนังสือเดินทาง'])[2]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2574']"); + await page.click("//div[text()='8']"); + + await page.click("(//div[@id='select-visa-type'])[2]"); + await page.waitForTimeout(2000); + await page.click("(//div[@role='option'])[1]"); + await page.fill("(//input[@id='input-visa-no'])[2]", '200222'); + await page.click("(//input[@aria-label='ออกให้วันที่'])[2]"); + await page.click("//div[text()='18']"); + await page.click("(//input[@aria-label='ใช้ได้ถึงวันที่'])[2]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2568']"); + await page.click("//div[text()='8']"); + await page.fill( + "(//input[@id='input-visa-place'])[2]", + 'กรมตรวจคนเข้าเมืองน่าน', + ); + await page.click("(//input[@aria-label='ให้อยู่ในราชอาณาจักรถึงวันที่'])[2]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2568']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-tm6'])[2]", '204422002'); + await page.click("(//input[@aria-label='วันที่เดินทางเข้ามาในประเทศ'])[2]"); + await page.click("//div[text()='18']"); + await page.click('id=submitBtn'); + await page.click('id=btn-ok-dialog'); + await page.waitForTimeout(2000); +}); + +test('Create Employee Not Input Personal Information OCR ', async () => { + await page.click('id=btn-add'); + await page.click('id=add-employee'); + await page.click("(//input[@id='select-employer-branch'])[2]"); + await page.click('id=select-employer-branch_0'); + await page.fill("(//input[@id='input-nrcNo'])[2]", '6282282246226'); + await page.fill("(//input[@id='input-first-name'])[2]", 'ปองพล'); + await page.fill("(//input[@id='input-last-name'])[2]", 'กันธะณะ'); + await page.fill("(//input[@id='input-first-name-en'])[2]", 'Pongpon'); + await page.fill("(//input[@id='input-last-name-en'])[2]", 'Kuntana'); + await page.click("(//input[@id='input-birth-date'])[2]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2536']"); + await page.click("//div[text()='8']"); + await page.click("(//div[@id='select-gender'])[2]"); + await page.click("//span[text()='หญิง']"); + await page.click("(//div[@id='select-nationality'])[2]"); + await page.waitForTimeout(2000); + await page.click("(//div[@role='option'])[1]"); + + await page.click("(//div[@id='select-visa-type'])[2]"); + await page.waitForTimeout(2000); + await page.click("(//div[@role='option'])[1]"); + await page.fill("(//input[@id='input-visa-no'])[2]", '200222'); + await page.click("(//input[@aria-label='ออกให้วันที่'])[2]"); + await page.click("//div[text()='18']"); + await page.click("(//input[@aria-label='ใช้ได้ถึงวันที่'])[2]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2568']"); + await page.click("//div[text()='8']"); + await page.fill( + "(//input[@id='input-visa-place'])[2]", + 'กรมตรวจคนเข้าเมืองน่าน', + ); + await page.click("(//input[@aria-label='ให้อยู่ในราชอาณาจักรถึงวันที่'])[2]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2568']"); + await page.click("//div[text()='12']"); + await page.fill("(//input[@id='input-tm6'])[2]", '204422002'); + await page.click("(//input[@aria-label='วันที่เดินทางเข้ามาในประเทศ'])[2]"); + await page.click("//div[text()='18']"); + await page.click('id=submitBtn'); + await page.click('id=cancelBtn'); + await page.waitForTimeout(2000); +}); + +test('Create Employee Not Input Visa Information OCR ', async () => { + await page.click('id=btn-add'); + await page.click('id=add-employee'); + + await page.click("(//input[@id='select-employer-branch'])[2]"); + await page.click('id=select-employer-branch_0'); + await page.fill("(//input[@id='input-nrcNo'])[2]", '6282282246226'); + await page.fill("(//input[@id='input-first-name'])[2]", 'ปองพล'); + await page.fill("(//input[@id='input-last-name'])[2]", 'กันธะณะ'); + await page.fill("(//input[@id='input-first-name-en'])[2]", 'Pongpon'); + await page.fill("(//input[@id='input-last-name-en'])[2]", 'Kuntana'); + await page.click("(//input[@id='input-birth-date'])[2]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2536']"); + await page.click("//div[text()='8']"); + await page.click("(//div[@id='select-gender'])[2]"); + await page.click("//span[text()='หญิง']"); + await page.click("(//div[@id='select-nationality'])[2]"); + await page.waitForTimeout(2000); + await page.click("(//div[@role='option'])[1]"); + await page.click("(//div[@id='select-passport-type'])[2]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill("(//input[@id='input-passport-no'])[2]", 'TH2862242226262'); + await page.fill("(//input[@id='input-passport-ref'])[2]", '2042022022426'); + await page.fill("(//input[@id='input-passport-place'])[2]", 'Bangkok'); + await page.click("(//div[@id='select-passport-country'])[2]"); + await page.waitForTimeout(2000); + await page.click("(//div[@role='option'])[1]"); + await page.click("(//input[@aria-label='วันที่ออกหนังสือเดินทาง'])[2]"); + await page.click("(//div[text()='2'])[1]"); + await page.click("(//input[@aria-label='วันหมดอายุหนังสือเดินทาง'])[2]"); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2574']"); + await page.click("//div[text()='8']"); + await page.click('id=submitBtn'); + await page.click('id=btn-ok-dialog'); + await page.waitForTimeout(2000); +}); diff --git a/tests/03-Admin-ManageCustomer/JWS_MC_018_SeachEmployee.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_018_SeachEmployee.spec.ts new file mode 100644 index 00000000..5877a356 --- /dev/null +++ b/tests/03-Admin-ManageCustomer/JWS_MC_018_SeachEmployee.spec.ts @@ -0,0 +1,44 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Selete Filter Employee Active', async () => { + await page.click('id=menu-icon-customer-management'); + await page.click('id=tab-employee'); + await page.fill('id=input-search', 'ปองพล กันธะณะ'); + await page.waitForTimeout(2000); + await page.fill('id=input-search', 'ปองพล'); + await page.waitForTimeout(2000); + await page.fill('id=input-search', 'กันธะณะ'); + await page.waitForTimeout(2000); + await page.fill('id=input-search', 'ไทย'); + await page.waitForTimeout(2000); + await page.fill('id=input-search', '6282282246226'); + await page.waitForTimeout(2000); + await page.fill('id=input-search', 'TH2862242226262'); + await page.waitForTimeout(2000); + await page.fill('id=input-search', 'บางรัก'); + await page.waitForTimeout(2000); +}); diff --git a/tests/03-Admin-ManageCustomer/JWS_MC_019_FliterStatusEmployee.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_019_FliterStatusEmployee.spec.ts new file mode 100644 index 00000000..1e066fa9 --- /dev/null +++ b/tests/03-Admin-ManageCustomer/JWS_MC_019_FliterStatusEmployee.spec.ts @@ -0,0 +1,45 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Selete Filter Employee Active', async () => { + await page.click('id=menu-icon-customer-management'); + await page.click('id=tab-employee'); + await page.click('id=select-status'); + await page.click('id=select-status_1'); + await page.waitForTimeout(2000); +}); + +test('Selete Filter Employee Inative', async () => { + await page.click('id=select-status'); + await page.click('id=select-status_2'); + await page.waitForTimeout(2000); +}); + +test('Selete Filter Employee All', async () => { + await page.click('id=select-status'); + await page.click('id=select-status_0'); + await page.waitForTimeout(2000); +}); diff --git a/tests/03-Admin-ManageCustomer/JWS_MC_020_DetailEmployee.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_020_DetailEmployee.spec.ts new file mode 100644 index 00000000..b212bbc3 --- /dev/null +++ b/tests/03-Admin-ManageCustomer/JWS_MC_020_DetailEmployee.spec.ts @@ -0,0 +1,33 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Select Detail Employee', async () => { + await page.click('id=menu-icon-customer-management'); + await page.click('id=tab-employee'); + await page.click("//button[@id='btn-dots-CORP000003-01-240003']"); + await page.click('id=view-detail-btn-undefined-view'); + await page.waitForTimeout(2000); +}); diff --git a/tests/03-Admin-ManageCustomer/JWS_MC_021_EditEmployee.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_021_EditEmployee.spec.ts new file mode 100644 index 00000000..88b10068 --- /dev/null +++ b/tests/03-Admin-ManageCustomer/JWS_MC_021_EditEmployee.spec.ts @@ -0,0 +1,33 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Edit Employee', async () => { + await page.click('id=menu-icon-customer-management'); + await page.click('id=tab-employee'); + await page.click("//button[@id='btn-dots-CORP000003-01-240003']"); + await page.click('id=view-detail-btn-undefined-edit'); + await page.waitForTimeout(2000); +}); diff --git a/tests/03-Admin-ManageCustomer/JWS_MC_022_DeleteEmployee.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_022_DeleteEmployee.spec.ts new file mode 100644 index 00000000..1a899d40 --- /dev/null +++ b/tests/03-Admin-ManageCustomer/JWS_MC_022_DeleteEmployee.spec.ts @@ -0,0 +1,33 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Delete Employee', async () => { + await page.click('id=menu-icon-customer-management'); + await page.click('id=tab-employee'); + await page.click("//button[@id='btn-dots-CORP000003-01-240003']"); + await page.click('id=view-detail-btn-undefined-edit'); + await page.waitForTimeout(2000); +}); diff --git a/tests/02-Admin-PersonnelManagement/JWS_PM_004_StatusPersonnel.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_023_StatusEmployee.spec.ts similarity index 63% rename from tests/02-Admin-PersonnelManagement/JWS_PM_004_StatusPersonnel.spec.ts rename to tests/03-Admin-ManageCustomer/JWS_MC_023_StatusEmployee.spec.ts index 3bd61959..222a4a1b 100644 --- a/tests/02-Admin-PersonnelManagement/JWS_PM_004_StatusPersonnel.spec.ts +++ b/tests/03-Admin-ManageCustomer/JWS_MC_023_StatusEmployee.spec.ts @@ -24,16 +24,17 @@ test('Login', async () => { // await page.click('id=acceptBtn'); }); -test('Status Close Personnel', async () => { - await page.click('id=menu-icon-personnel-management'); - await page.click("(//div[@class='full-width text-right']//button)[1]"); - await page.click("//div[contains(@class,'q-toggle__thumb absolute')]"); - await page.keyboard.press('Escape'); +test('Status off Employee', async () => { + await page.click('id=menu-icon-customer-management'); + await page.click('id=tab-employee'); + await page.click("//button[@id='btn-dots-PERS000001-01-240001']"); + await page.click('id=view-detail-btn-undefined-status'); await page.waitForTimeout(2000); + await page.keyboard.press('Escape'); }); -test('Status Open Personnel', async () => { - await page.click("(//div[@class='full-width text-right']//button)[1]"); - await page.click("//div[contains(@class,'q-toggle__thumb absolute')]"); +test('Status on Employee', async () => { + await page.click("//button[@id='btn-dots-PERS000001-01-240001']"); + await page.click('id=view-detail-btn-undefined-status'); await page.waitForTimeout(2000); }); diff --git a/tests/03-Admin-ManageCustomer/JWS_MC_024_DropdownEmployeetype.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_024_DropdownEmployeetype.spec.ts new file mode 100644 index 00000000..64d7694f --- /dev/null +++ b/tests/03-Admin-ManageCustomer/JWS_MC_024_DropdownEmployeetype.spec.ts @@ -0,0 +1,72 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; +import { escape } from 'querystring'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Select Dropdown Employee Type Off', async () => { + await page.click('id=menu-icon-customer-management'); + await page.click('id=tab-employee'); + await page.click('id=select-field'); + await page.click('id=select-field_0'); + await page.waitForTimeout(2000); + await page.click('id=select-field_1'); + await page.waitForTimeout(2000); + await page.click('id=select-field_2'); + await page.waitForTimeout(2000); + await page.click('id=select-field_3'); + await page.waitForTimeout(2000); + await page.click('id=select-field_4'); + await page.waitForTimeout(2000); + await page.click('id=select-field_5'); + await page.waitForTimeout(2000); + await page.click('id=select-field_6'); + await page.waitForTimeout(2000); + await page.click('id=select-field_7'); + await page.waitForTimeout(2000); + await page.keyboard.press('Escape'); + await page.waitForTimeout(2000); +}); + +test('Select Dropdown Employee Type on', async () => { + await page.click('id=select-field'); + await page.click('id=select-field_0'); + await page.waitForTimeout(2000); + await page.click('id=select-field_1'); + await page.waitForTimeout(2000); + await page.click('id=select-field_2'); + await page.waitForTimeout(2000); + await page.click('id=select-field_3'); + await page.waitForTimeout(2000); + await page.click('id=select-field_4'); + await page.waitForTimeout(2000); + await page.click('id=select-field_5'); + await page.waitForTimeout(2000); + await page.click('id=select-field_6'); + await page.waitForTimeout(2000); + await page.click('id=select-field_7'); + await page.waitForTimeout(2000); + await page.keyboard.press('Escape'); + await page.waitForTimeout(2000); +}); diff --git a/tests/03-Admin-ManageCustomer/JWS_MC_025_CreateSubBranchNaturalperson.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_025_CreateSubBranchNaturalperson.spec.ts new file mode 100644 index 00000000..7fd9f43b --- /dev/null +++ b/tests/03-Admin-ManageCustomer/JWS_MC_025_CreateSubBranchNaturalperson.spec.ts @@ -0,0 +1,71 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('Open Natural Person', async () => { + await page.click('id=menu-icon-customer-management'); + await page.click('id=row-table-โคโม่'); + await page.click("(//div[@id='btn-add']//a)[1]"); + await page.click("(//div[@id='btn-add']//div)[2]"); + await page.waitForTimeout(2000); +}); + +test('Create Sub Branch Natural Person', async () => { + await page.fill('id=form-dialog-input-branch-no', '20'); + await page.fill('id=form-dialog-input-customer-name', 'สยาม'); + await page.fill('id=form-dialog-input-customer-english-name', 'siam'); + await page.fill('id=form-dialog-input-address-0', '20/022'); + await page.click('id=form-dialog-select-province-0'); + await page.click("//div[@role='option']"); + await page.click('id=form-dialog-select-district-0'); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.click('id=form-dialog-select-sub-district-0'); + await page.waitForTimeout(1000); + await page.click("//div[@role='option']"); + await page.fill('id=form-dialog-input-address-en-0', '20/022'); + await page.fill('id=form-dialog-input-employment-office', 'กรุงเทพมหานคร'); + await page.click('id=form-dialog-select-business-type'); + await page.click("//span[text()='ประมง']"); + await page.click("(//div[@id='form-dialog-select-job-position'])[1]"); + await page.click("(//div[@role='option'])[1]"); + await page.fill( + 'id=form-dialog-input-job-description', + 'ตรวจสอบการทำการลักษณะงาน', + ); + await page.click('id=form-dialog-input-start-date'); + await page.click("(//button[@class='dp__btn dp__month_year_select'])[2]"); + await page.click("//div[text()='2561']"); + await page.click("//div[text()='12']"); + await page.fill('id=form-dialog-input-sales-person', 'พนักงานขาย'); + await page.fill('id=form-dialog-input-mail', 'jws@local.com'); + await page.fill('id=form-dialog-input-telephone', '0864228464'); + // await page.setInputFiles( + // "//input[@id='f_55bbcb5d-4316-43c8-93cf-99c4f1f60115']", + // '/Users/linping/Desktop/Chamomind&FrappeT/JWS_TestScript/tests/Datafile/Pic1.jpg', + // ); // UploadFile + await page.click("(//button[@id='submitBtn'])[2]"); + await page.waitForTimeout(2000); +}); diff --git a/tests/01-Admin-BranchManagement/JWS_BM_006_ViewDetail.spec.ts b/tests/03-Admin-ManageCustomer/JWS_MC_026_CreateSubBranchLegalentitly.spec.ts similarity index 70% rename from tests/01-Admin-BranchManagement/JWS_BM_006_ViewDetail.spec.ts rename to tests/03-Admin-ManageCustomer/JWS_MC_026_CreateSubBranchLegalentitly.spec.ts index 9b1351bd..503172f4 100644 --- a/tests/01-Admin-BranchManagement/JWS_BM_006_ViewDetail.spec.ts +++ b/tests/03-Admin-ManageCustomer/JWS_MC_026_CreateSubBranchLegalentitly.spec.ts @@ -24,10 +24,8 @@ test('Login', async () => { // await page.click('id=acceptBtn'); }); -test('View Detail', async () => { - await page.click('id=menu-icon-branch-management'); - await page.click('id=view-detail-btn-สีลม'); - await page.click('id=view-detail-btn-สีลม-view'); - await page.waitForTimeout(4000); - await page.click('id=closeDialog'); +test('Open Legal Entitly ', async () => { + await page.click('id=menu-icon-customer-management'); + + await page.waitForTimeout(2000); }); diff --git a/tests/04-ProductandService/JWS_PD_001_CreateProductandServiceGroup.spec.ts b/tests/04-ProductandService/JWS_PD_001_CreateProductandServiceGroup.spec.ts new file mode 100644 index 00000000..92e1e4d5 --- /dev/null +++ b/tests/04-ProductandService/JWS_PD_001_CreateProductandServiceGroup.spec.ts @@ -0,0 +1,115 @@ +import { test, expect, Page } from '@playwright/test'; +import { strictEqual } from 'assert'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); +}); + +test.afterAll(async () => { + if (page !== undefined) { + await page.close(); + } +}); + +test('Login', async () => { + // Login + await page.goto('http://192.168.1.90:20001/'); + await expect(page).toHaveTitle(/^Sign in to /); + await page.fill("input[name='username']", 'admin'); + await page.fill("input[name='password']", '1234'); + await page.click('id=kc-login'); + await page.waitForTimeout(2000); + // await page.click('id=acceptBtn'); +}); + +test('ทดสอบการเพิ่มกลุ่มสินค้าและบริการ', async () => { + await page.click('id=menu-icon-product-service'); + + try { + // เพิ่มกลุ่มสินค้าและบริการ + await page.click('id=btn-add'); + await page.click('id=btn-add-product-group'); + + // กรอกข้อมูลกลุ่มสินค้าและบริการ + await page.fill("(//input[@id='input-name'])[2]", 'ประกัน'); + await page.fill("(//textarea[@id='input-detail'])[2]", 'รายละเอียดประกัน'); + await page.fill("(//textarea[@id='input-remark'])[2]", 'หมายเหตุประกัน'); + + // บันทึกการสร้างกลุ่มสินค้นและบริการ + await page.click('id=btn-form-submit'); + + // ตรวจสอบหลังทำการสร้างกลุ่มสินค้าและบริการ + const newProductAndServiceLocator = page.locator( + "//div[normalize-space(text())='ประกัน']", + ); + await newProductAndServiceLocator.waitFor({ state: 'visible' }); + + // ดึงข้อความให้ตรงจาก XPath + + const newProductAndServiceName = + await newProductAndServiceLocator.textContent(); + + // ตรวจสอบความถูกต้องหลังทำการสร้างกลุ่มสินค้าและบริการ + if (newProductAndServiceName !== null) { + const trimmedName = newProductAndServiceName.trim(); + expect(trimmedName).toBe('ประกัน'); + console.log('การตรวจสอบสำเร็จ : ถูกต้อง'); + } else { + throw new Error('ไม่พบข้อมูลที่บันทึก'); + } + } catch (error) { + console.error('เกิดข้อผิดการในการทดสอบ'); + throw error; + } + + await page.waitForTimeout(2000); +}); + +test('ทดสอบการเพิ่มประเภท', async () => { + // เข้าสู่หน้าหลุ่มสินค้าและบริการ + await page.click("(//div[@id='tree-enter-ประกัน']//div)[1]"); + + try { + // เพิ่มกลุ่มสินค้าและบริการ + await page.click('id=btn-add'); + await page.click('id=btn-add-service'); + + // กรอกข้อมูลประเภทส่วน "ข้อมูลประเภท" + await page.fill('id=input-service-code', 'MOU'); + await page.fill('id=input-service-name', 'ประกันภัยแบบกลุ่ม'); + await page.fill('id=input-service-description', 'รายละเอียดประภัยแบบกลุ่ม'); + + // เพิ่มคุณสมบัติส่วน "คุณสมบัติของประเภท" + await page.click('id=btn-capitalize'); + + // บันทึกการสร้างกลุ่มสินค้นและบริการ + await page.click('id=btn-form-submit'); + + // ตรวจสอบหลังทำการสร้างกลุ่มสินค้าและบริการ + const newProductAndServiceLocator = page.locator( + "//div[normalize-space(text())='ประกัน']", + ); + await newProductAndServiceLocator.waitFor({ state: 'visible' }); + + // ดึงข้อความให้ตรงจาก XPath + + const newProductAndServiceName = + await newProductAndServiceLocator.textContent(); + + // ตรวจสอบความถูกต้องหลังทำการสร้างกลุ่มสินค้าและบริการ + if (newProductAndServiceName !== null) { + const trimmedName = newProductAndServiceName.trim(); + expect(trimmedName).toBe('ประกัน'); + console.log('การตรวจสอบสำเร็จ : ถูกต้อง'); + } else { + throw new Error('ไม่พบข้อมูลที่บันทึก'); + } + } catch (error) { + console.error('เกิดข้อผิดการในการทดสอบ'); + throw error; + } + + await page.waitForTimeout(2000); +}); diff --git a/tests/Datafile/Pic1.jpg b/tests/Datafile/Pic1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..368466813acfb94179d60bbf345ad7c313c53b01 GIT binary patch literal 150709 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 literal 0 HcmV?d00001