diff --git a/Project/Code/app/Http/Controllers/HighlightController.php b/Project/Code/app/Http/Controllers/HighlightController.php index bc3da23d..718d8afe 100644 --- a/Project/Code/app/Http/Controllers/HighlightController.php +++ b/Project/Code/app/Http/Controllers/HighlightController.php @@ -99,8 +99,10 @@ public function update(Request $request, $id) 'title' => 'required|string|max:255', 'detail' => 'required|string', 'images.*' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048', + 'tags' => 'required|string', ]); + // อัปเดต title และ detail $highlight->title = $request->title; $highlight->detail = $request->detail; $highlight->save(); @@ -124,7 +126,20 @@ public function update(Request $request, $id) } } - // แก้ข้อความ redirect ให้ถูกต้อง + // จัดการ tags: รับค่า tags เป็น comma separated string + $tags = explode(',', $request->tags); + // ปรับ trim และกรองค่าว่างออก + $tags = array_filter(array_map('trim', $tags)); + + // ลบ tag เก่าทั้งหมดออก + $highlight->tags()->detach(); + + // เพิ่ม tag ใหม่ + foreach ($tags as $tagName) { + $tag = Tag::firstOrCreate(['name' => $tagName]); + $highlight->tags()->attach($tag); + } + return redirect()->route('highlight.view')->with('success', 'Highlight updated successfully!'); } @@ -146,4 +161,4 @@ public function destroy($id) // เปลี่ยน redirect ไปที่หน้า view return redirect()->route('highlight.view')->with('success', 'Highlight deleted successfully!'); } -} +} \ No newline at end of file diff --git a/Project/Test/UAT/UAT_Banner_Staff.robot b/Project/Test/UAT/UAT_Banner_Staff.robot new file mode 100644 index 00000000..be352b99 --- /dev/null +++ b/Project/Test/UAT/UAT_Banner_Staff.robot @@ -0,0 +1,12 @@ +*** Settings *** +Library SeleniumLibrary + +*** Variables *** +${SERVER} localhost:8000 +${STAFF_USERNAME} staff@gmail.com +${STAFF_PASSWORD} 123456789 +${LOGIN URL} http://${SERVER}/login +${STAFF URL} http://${SERVER}/dashboard +${HIGHLIGHT URL} http://${SERVER}/highlight +${CHROME_BROWSER_PATH} ${EXECDIR}${/}ChromeForTesting${/}chrome.exe +${CHROME_DRIVER_PATH} ${EXECDIR}${/}ChromeForTesting${/}chromedriver.exe \ No newline at end of file diff --git a/Project/Test/UAT/UAT_Highlight_Staff.robot b/Project/Test/UAT/UAT_Highlight_Staff.robot index 17321bdc..9362c00f 100644 --- a/Project/Test/UAT/UAT_Highlight_Staff.robot +++ b/Project/Test/UAT/UAT_Highlight_Staff.robot @@ -58,19 +58,22 @@ Logout Dashboard *** Test Cases *** As Administrative Staff, I want to check highlight detail that created [Tags] UAT001-CheckHighlightDetail + # [Enter] Login page Open Browser To Login Page Staff Login + # [Enter] Highlight page Click Element xpath=//a[contains(@href,'highlight')] - # [Highlight_1] Fill Highlight + # [Highlight_1] Fill Highlight title and detail Input Text id=title ${TITLE_1} Input Text id=detail ${DETAIL_1} - # [Highlight_1] Upload image + # [Highlight_1] Upload main image ${IMAGE_PATH}= Set Variable ${EXECDIR}${/}highlight_image_test01.jpg Choose File id=thumbnail ${IMAGE_PATH} sleep 2s + # [Highlight_1] Upload additional image ${IMAGE_PATH}= Set Variable ${EXECDIR}${/}highlight_image_test01.jpg Choose File id=additional_thumbnails ${IMAGE_PATH} sleep 2s @@ -88,7 +91,7 @@ As Administrative Staff, I want to check highlight detail that created Press Keys id=tags ENTER sleep 2s - # [Highlight_1] Submit Form + # [Submit] Highlight form Execute JavaScript document.querySelector("button.btn-primary").scrollIntoView({behavior: "smooth", block: "center"}); Sleep 1s Wait Until Element Is Visible xpath=//button[contains(.,'Upload')] @@ -96,6 +99,7 @@ As Administrative Staff, I want to check highlight detail that created Execute JavaScript document.querySelector("button[type='submit']").click(); sleep 2s + # [Check] Highlight count ${highlight_count}= Get Element Count xpath=//a[contains(@href,'highlights') and contains(@class,'btn-outline-success')] Log Found ${highlight_count} highlights sleep 2s @@ -105,34 +109,40 @@ As Administrative Staff, I want to check highlight detail that created Click Element xpath=(//a[contains(@href,'highlights') and contains(@class,'btn-outline-primary')])[${highlight_count}] sleep 2s - # [Highlight_1] Highlight detail page + # [Verify] Highlight detail content Wait Until Page Contains ${TITLE_1} Wait Until Page Contains ${DETAIL_1} - # Wait Until Page Contains KKU - # Wait Until Page Contains มข. - # Wait Until Page Contains cpkku - # Wait Until Page Contains computing - # Wait Until Page Contains phet + Wait Until Page Contains KKU + Wait Until Page Contains มข. + Wait Until Page Contains cpkku + Wait Until Page Contains computing + Wait Until Page Contains phet + + # [Verify] Additional image loaded + ${is_loaded}= Execute JavaScript return document.querySelector("img[src*='storage/thumbnails/additional']").complete && document.querySelector("img[src*='storage/thumbnails/additional']").naturalHeight !== 0 + Should Be True ${is_loaded} # [Enter] Manage Highlight Wait Until Element Is Visible xpath=//a[contains(text(),'Back')] Click Element xpath=//a[contains(text(),'Back')] - # [Logout] Logout + # [Logout] Dashboard Logout Dashboard [Teardown] Close All Browsers As Administrative Staff, I want to edit highlight detail that created [Tags] UAT004-EditHighlight + # [Enter] Login page Open Browser To Login Page Staff Login + # [Enter] Highlight page Click Element xpath=//a[contains(@href,'highlight')] # [Enter] Manage Highlight Wait Until Element Is Visible xpath=//a[contains(text(),'Manage Highlight')] Click Element xpath=//a[contains(text(),'Manage Highlight')] - # Count the number of edit buttons to determine the latest + # [Check] Highlight count ${highlight_count}= Get Element Count xpath=//a[contains(@href,'highlights') and contains(@class,'btn-outline-success')] Log Found ${highlight_count} highlights @@ -140,89 +150,84 @@ As Administrative Staff, I want to edit highlight detail that created Wait Until Element Is Visible xpath=(//a[contains(@href,'highlights') and contains(@class,'btn-outline-success')])[${highlight_count}] Click Element xpath=(//a[contains(@href,'highlights') and contains(@class,'btn-outline-success')])[${highlight_count}] - # [Edit_Highlight_1] Change highlight_1 to new values + # [Edit] Change highlight to new values Input Text name=title ${TITLE_2} Input Text name=detail ${DETAIL_2} ${IMAGE_PATH}= Set Variable ${EXECDIR}${/}highlight_image_test02.jpg Choose File name=thumbnails[] ${IMAGE_PATH} Input Text name=tags KKU,มข.,cpkku,cp,ITEX2025 - # Submit the edited highlight form + # [Submit] Edited highlight form Wait Until Element Is Visible xpath=//button[@type='submit' and contains(@class,'btn-primary')] Execute JavaScript document.querySelector("button[type='submit'].btn-primary").scrollIntoView({behavior: "smooth", block: "center"}); Sleep 1s - Execute JavaScript document.querySelector("button[type='submit'].btn-primary").click(); + Execute JavaScript document.querySelector("button[type='submit'].btn-primary').click(); + # [Enter] Highlight view page Sleep 3s Go To ${HIGHLIGHT URL}/view Sleep 2s - # Count the number of edit buttons to determine the latest + # [Check] Updated highlight count ${highlight_count}= Get Element Count xpath=//a[contains(@href,'highlights') and contains(@class,'btn-outline-success')] Log Found ${highlight_count} highlights - # [Enter] Highlight edit page - target the most recent highlight (last in list if order is oldest first) + # [Enter] Updated highlight detail page Wait Until Element Is Visible xpath=(//a[contains(@href,'highlights') and contains(@class,'btn-outline-primary')])[${highlight_count}] Click Element xpath=(//a[contains(@href,'highlights') and contains(@class,'btn-outline-primary')])[${highlight_count}] - - # [Highlight_1] Check detail page elements directly instead of using source - Wait Until Page Contains ${TITLE_2} - Wait Until Page Contains ${DETAIL_2} - - # # Check for tags - # Page Should Contain Element xpath=//span[contains(@class,'badge') and contains(text(),'KKU')] - # Page Should Contain Element xpath=//span[contains(@class,'badge') and contains(text(),'มข.')] - # Page Should Contain Element xpath=//span[contains(@class,'badge') and contains(text(),'cpkku')] - # Page Should Contain Element xpath=//span[contains(@class,'badge') and contains(text(),'cp')] - # Page Should Contain Element xpath=//span[contains(@class,'badge') and contains(text(),'ITEX2025')] - - # [Highlight_2] Check data + # [Verify] Updated highlight data Wait Until Page Contains ${TITLE_2} Wait Until Page Contains ${DETAIL_2} - # Check for tags - # Wait Until Page Contains KKU - # Wait Until Page Contains มข. - # Wait Until Page Contains cpkku - # Wait Until Page Contains cp - # Wait Until Page Contains ITEX2025 + # [Verify] Updated tags + Wait Until Page Contains KKU + Wait Until Page Contains มข. + Wait Until Page Contains cpkku + Wait Until Page Contains cp + Wait Until Page Contains ITEX2025 + + # [Verify] Updated image loaded + ${is_loaded}= Execute JavaScript return document.querySelector("img[src*='storage/thumbnails/additional']").complete && document.querySelector("img[src*='storage/thumbnails/additional']").naturalHeight !== 0 + Should Be True ${is_loaded} - # [Logout] Logout + # [Logout] Dashboard Logout Dashboard [Teardown] Close All Browsers As Administrative Staff, I want to delete highlight that created [Tags] UAT004-DeleteHighlight + # [Enter] Login page Open Browser To Login Page Staff Login + # [Enter] Highlight page Click Element xpath=//a[contains(@href,'highlight')] # [Enter] Manage Highlight Wait Until Element Is Visible xpath=//a[contains(text(),'Manage Highlight')] Click Element xpath=//a[contains(text(),'Manage Highlight')] - # Count the number of edit buttons to determine the latest + # [Check] Highlight count ${highlight_count}= Get Element Count xpath=//a[contains(@href,'highlights') and contains(@class,'btn-outline-success')] Log Found ${highlight_count} highlights - # [Delete_Highlight_1] Highlight - using the button inside the form + # [Delete] Highlight using button Wait Until Element Is Visible xpath=(//button[contains(@class,'btn-outline-danger') or contains(@class,'show_confirm')])[${highlight_count}] Execute JavaScript document.querySelector("button.show_confirm").click(); - # [Delete_Highlight_1] Handle the confirmation dialog for first highlight + # [Confirm] Delete in confirmation dialog Wait Until Element Is Visible xpath=//div[contains(@class,'swal-modal')] Wait Until Element Is Visible xpath=//button[contains(@class,'swal-button--confirm')] Click Element xpath=//button[contains(@class,'swal-button--confirm')] Sleep 3s # Wait for deletion to complete - # [Delete_Highlight_1] Handle the success modal after deletion + # [Verify] Delete success message Wait Until Element Is Visible xpath=//div[contains(@class,'swal-modal')] Wait Until Element Is Visible xpath=//div[contains(text(),'Deleted Successfully')] Wait Until Element Is Visible xpath=//button[contains(@class,'swal-button--confirm')] Click Element xpath=//button[contains(@class,'swal-button--confirm')] Sleep 2s - # [Logout] Logout + # [Logout] Dashboard Logout Dashboard [Teardown] Close All Browsers diff --git a/Project/Test/UAT/UAT_Highlight_Visitor.robot b/Project/Test/UAT/UAT_Highlight_Visitor.robot new file mode 100644 index 00000000..c99e4298 --- /dev/null +++ b/Project/Test/UAT/UAT_Highlight_Visitor.robot @@ -0,0 +1,288 @@ +*** Settings *** +Library SeleniumLibrary + +*** Variables *** +${SERVER} localhost:8000 +${STAFF_USERNAME} staff@gmail.com +${STAFF_PASSWORD} 123456789 +${HOME URL} http://${SERVER}/ +${LOGIN URL} http://${SERVER}/login +${STAFF URL} http://${SERVER}/dashboard +${HIGHLIGHT URL} http://${SERVER}/highlight +${CHROME_BROWSER_PATH} ${EXECDIR}${/}ChromeForTesting${/}chrome.exe +${CHROME_DRIVER_PATH} ${EXECDIR}${/}ChromeForTesting${/}chromedriver.exe + +# Title Variables +${TITLE_1} วิทยาลัยการคอมพิวเตอร์ มหาวิทยาลัยขอนแก่น ขอแสดงความยินดีกับ อาจารย์ ดร.เพชร อิ่มทองคำ อาจารย์ประจำวิทยาลัยการคอมพิวเตอร์ เนื่องในโอกาสได้รับแต่งตั้งให้ดำรงตำแหน่ง "ผู้ช่วยศาสตราจารย์" +${DETAIL_1} วิทยาลัยการคอมพิวเตอร์ มหาวิทยาลัยขอนแก่น ขอแสดงความยินดีกับ อาจารย์ ดร.เพชร อิ่มทองคำ อาจารย์ประจำวิทยาลัยการคอมพิวเตอร์ เนื่องในโอกาสได้รับแต่งตั้งให้ดำรงตำแหน่ง "ผู้ช่วยศาสตราจารย์" ในสาขาวิชาเทคโนโลยีสารสนเทศตั้งแต่วันที่ 16 พฤษภาคม 2567 ตามที่สภามหาวิทยาลัยขอนแก่นได้มีมติอนุมัติแต่งตั้งให้ดำรงตำแหน่งทางวิชาการในคราวการประชุมครั้งที่ 3/2568 เมื่อวันที่ 5 มีนาคม 2568 +${TITLE_2} นักวิจัย มข. และบริษัทมิตรผล จับมือนำ AI คัดแยกพันธุ์อ้อยสู่เวทีนานาชาติ ในงาน ITEX 2025 +${DETAIL_2} วิทยาลัยการคอมพิวเตอร์ มหาวิทยาลัยขอนแก่น ขอแสดงความยินดีกับ รศ. ดร.วรารัตน์ สงฆ์แป้น และคณะทีมวิจัย จากบริษัท มิตรผลวิจัย พัฒนาอ้อยและน้ำตาล จำกัด ในผลงานเรื่อง“การพัฒนาแบบจำลองปัญญาประดิษฐ์การคัดแยกพันธุ์อ้อยด้วยการเรียนรู้เครื่องและการเรียนรู้เชิงลึก" + +*** Keywords *** +Open Browser To Login Page + ${chrome_options}= Evaluate sys.modules['selenium.webdriver'].ChromeOptions() sys + ${chrome_options.binary_location}= Set Variable ${CHROME_BROWSER_PATH} + Call Method ${chrome_options} add_argument --no-sandbox + ${service}= Evaluate sys.modules["selenium.webdriver.chrome.service"].Service(executable_path=r"${CHROME_DRIVER_PATH}") + Create Webdriver Chrome options=${chrome_options} service=${service} + Go To ${LOGIN URL} + Login Page Should Be Open + Maximize Browser Window + +Login Page Should Be Open + Location Should Be ${LOGIN URL} + +Open Browser To Staff Page + ${chrome_options}= Evaluate sys.modules['selenium.webdriver'].ChromeOptions() sys + ${chrome_options.binary_location}= Set Variable ${CHROME_BROWSER_PATH} + Call Method ${chrome_options} add_argument --no-sandbox + ${service}= Evaluate sys.modules["selenium.webdriver.chrome.service"].Service(executable_path=r"${CHROME_DRIVER_PATH}") + Create Webdriver Chrome options=${chrome_options} service=${service} + Go To ${STAFF URL} + Staff Page Should Be Open + Maximize Browser Window + +Staff Page Should Be Open + Location Should Be ${STAFF URL} + +Open Browser To Home Page + ${chrome_options}= Evaluate sys.modules['selenium.webdriver'].ChromeOptions() sys + ${chrome_options.binary_location}= Set Variable ${CHROME_BROWSER_PATH} + Call Method ${chrome_options} add_argument --no-sandbox + ${service}= Evaluate sys.modules["selenium.webdriver.chrome.service"].Service(executable_path=r"${CHROME_DRIVER_PATH}") + Create Webdriver Chrome options=${chrome_options} service=${service} + Go To ${HOME URL} + Home Page Should Be Open + Maximize Browser Window + +Home Page Should Be Open + Location Should Be ${HOME URL} + +Staff Login + Input Text id=username ${STAFF_USERNAME} + Input Text id=password ${STAFF_PASSWORD} + Sleep 2s + Click Button xpath=//button[@type='submit'] + Location Should Be ${STAFF URL} + +Logout Dashboard + Wait Until Element Is Visible xpath=//a[contains(text(),'Logout')] + Click Element xpath=//a[contains(text(),'Logout')] + +Staff Add Highlight + Open Browser To Login Page + Staff Login + Click Element xpath=//a[contains(@href,'highlight')] + # [Highlight_1] Fill Highlight + Input Text id=title ${TITLE_1} + Input Text id=detail ${DETAIL_1} + + # [Highlight_1] Upload image + ${IMAGE_PATH}= Set Variable ${EXECDIR}${/}highlight_image_test01.jpg + Choose File id=thumbnail ${IMAGE_PATH} + ${IMAGE_PATH}= Set Variable ${EXECDIR}${/}highlight_image_test01.jpg + Choose File id=additional_thumbnails ${IMAGE_PATH} + + # [Highlight_1] Enter tags + Input Text id=tags KKU + Press Keys id=tags ENTER + Input Text id=tags มข. + Press Keys id=tags ENTER + Input Text id=tags cpkku + Press Keys id=tags ENTER + Input Text id=tags computing + Press Keys id=tags ENTER + Input Text id=tags phet + Press Keys id=tags ENTER + + # [Highlight_1] Submit Form + Execute JavaScript document.querySelector("button.btn-primary").scrollIntoView({behavior: "smooth", block: "center"}); + Wait Until Element Is Visible xpath=//button[contains(.,'Upload')] + Wait Until Element Is Enabled xpath=//button[contains(.,'Upload')] + Execute JavaScript document.querySelector("button[type='submit']").click(); + + Click Element xpath=//a[contains(@href,'highlight')] + + # [Highlight_2] Fill Highlight + Input Text id=title ${TITLE_2} + Input Text id=detail ${DETAIL_2} + + # [Highlight_2] Upload image + ${IMAGE_PATH}= Set Variable ${EXECDIR}${/}highlight_image_test02.jpg + Choose File id=thumbnail ${IMAGE_PATH} + ${IMAGE_PATH}= Set Variable ${EXECDIR}${/}highlight_image_test02.jpg + Choose File id=additional_thumbnails ${IMAGE_PATH} + + # [Highlight_2] Enter tags + Input Text id=tags KKU + Press Keys id=tags ENTER + Input Text id=tags มข. + Press Keys id=tags ENTER + Input Text id=tags cpkku + Press Keys id=tags ENTER + Input Text id=tags cp + Press Keys id=tags ENTER + Input Text id=tags ITEX2025 + Press Keys id=tags ENTER + + # [Highlight_2] Submit Form + Execute JavaScript document.querySelector("button.btn-primary").scrollIntoView({behavior: "smooth", block: "center"}); + Wait Until Element Is Visible xpath=//button[contains(.,'Upload')] + Wait Until Element Is Enabled xpath=//button[contains(.,'Upload')] + Execute JavaScript document.querySelector("button[type='submit']").click(); + + # [Logout] Logout + Logout Dashboard + [Teardown] Close All Browsers + + +*** Test Cases *** +As Visitor, I want to verify no highlights are available + [Tags] UAT001-EmptyHighlight Visitor + # [Enter] Homepage as visitor + Open Browser To Home Page + + # [Check] Empty highlight state + ${highlight_rows}= Get Element Count xpath=//div[contains(@class,'highlight-row')]/div[contains(@class,'highlight-card')] + + # [Verify] No highlights displayed + Run Keyword If ${highlight_rows} == 0 Run Keywords + ... Log No highlights found - empty state verified AND + ... Page Should Not Contain Element xpath=//div[contains(@class,'highlight-card')] + + [Teardown] Close Browser + +As Visitor, I want to see highlights on homepage + [Tags] UAT002-ViewHighlights Visitor + # [Setup] Add test highlights + Staff Add Highlight + + # [Enter] Homepage as visitor + Open Browser To Home Page + + # [Check] Highlight cards visible + Wait Until Element Is Visible xpath=//div[contains(@class,'highlight-card')] + + # [Verify] Multiple highlight cards present + ${card_count}= Get Element Count xpath=//div[contains(@class,'highlight-card')] + Should Be True ${card_count} >= 2 Expected at least 2 highlight cards, but found ${card_count} + + # [Check] Images loaded properly + Sleep 2s + ${image_loaded}= Execute JavaScript return document.querySelector('.highlight-card img').complete && document.querySelector('.highlight-card img').naturalHeight !== 0 + Should Be True ${image_loaded} + + # [Verify] Highlight titles match expected values + Page Should Contain Element xpath=//h3[contains(@class,'highlight-title') and contains(text(),'${TITLE_1}')] + Page Should Contain Element xpath=//h3[contains(@class,'highlight-title') and contains(text(),'${TITLE_2}')] + + # [Setup] Longer timeout for stability + Set Selenium Timeout 15s + + # [Check] Tag elements present and accessible + ${tags_present}= Execute JavaScript + ... return Array.from(document.querySelectorAll('.tags-list .tag-link')).map(el => el.textContent.trim()).join(',') + + Log Found tags: ${tags_present} + + # [Verify] Expected tags are present + Should Contain ${tags_present} KKU + Should Contain ${tags_present} มข. + Should Contain ${tags_present} cpkku + Should Contain ${tags_present} cp + Should Contain ${tags_present} computing + + [Teardown] Close Browser + +As Visitor, I want to see highlight details + [Tags] UAT003-ViewHighlightDetail Visitor + # [Enter] Homepage as visitor + Open Browser To Home Page + + # [Check] Highlight cards visible + Wait Until Element Is Visible xpath=//div[contains(@class,'highlight-card')] + + # [Store] First highlight title for comparison + ${first_highlight_title}= Get Text xpath=(//div[contains(@class,'highlight-card')]//h3[contains(@class,'highlight-title')])[1] + Log First highlight title: ${first_highlight_title} + + # [Store] First highlight URL + ${first_card_link}= Get Element Attribute xpath=(//div[contains(@class,'highlight-card')]//a[contains(@href,'showHighlight')])[1] href + + # [Click] First highlight to view details + Click Element xpath=(//div[contains(@class,'highlight-card')]//a[contains(@href,'showHighlight')])[1] + + # [Verify] Navigation to correct detail page + Location Should Contain showHighlight + + # [Setup] Longer timeout for detail page elements + Set Selenium Timeout 10s + + # [Verify] Detail page title matches card title + Wait Until Element Is Visible xpath=//h1[contains(@class,'highlight-title')] + ${detail_page_title}= Get Text xpath=//h1[contains(@class,'highlight-title')] + Should Be Equal ${detail_page_title} ${first_highlight_title} + + # [Verify] Detail content is present + Page Should Contain Element xpath=//p[contains(@class,'highlight-detail')] + ${detail_text}= Get Text xpath=//p[contains(@class,'highlight-detail')] + Should Not Be Empty ${detail_text} + + # [Check] Main thumbnail image + Page Should Contain Element xpath=//img[contains(@class,'highlight-thumbnail')] + + # [Verify] Main image loaded correctly + ${main_image_loaded}= Execute JavaScript + ... return document.querySelector('img.highlight-thumbnail').complete && document.querySelector('img.highlight-thumbnail').naturalHeight !== 0; + Should Be True ${main_image_loaded} Main image did not load properly + + # [Check] Additional images if present + ${additional_images_exist}= Run Keyword And Return Status + ... Page Should Contain Element xpath=//img[contains(@class,'additional-image')] + + # [View] Additional images if they exist + Run Keyword If ${additional_images_exist} + ... Execute JavaScript document.querySelector('img.additional-image').scrollIntoView({behavior:"smooth", block:"center"}) + + # [Setup] Wait for scrolling + Run Keyword If ${additional_images_exist} Sleep 1s + + # [Setup] Variable for additional image check + ${additional_image_loaded}= Set Variable ${FALSE} + + # [Check] Additional image loading state + ${js_result}= Run Keyword If ${additional_images_exist} + ... Execute JavaScript return document.querySelector('img.additional-image').complete && document.querySelector('img.additional-image').naturalHeight !== 0 + + # [Store] Additional image load status + ${additional_image_loaded}= Set Variable If ${additional_images_exist} ${js_result} ${FALSE} + + # [Verify] Additional image loaded correctly if present + Run Keyword If ${additional_images_exist} + ... Should Be True ${additional_image_loaded} Additional image did not load properly + + # [Check] Tag links present + Page Should Contain Element xpath=//a[contains(@class,'tag-link')] + + # [Verify] Expected tags exist + Page Should Contain Element xpath=//a[contains(@class,'tag-link') and contains(text(),'KKU')] + Page Should Contain Element xpath=//a[contains(@class,'tag-link') and contains(text(),'มข.')] + Page Should Contain Element xpath=//a[contains(@class,'tag-link') and contains(text(),'cpkku')] + + # [Verify] Tag container structure + Page Should Contain Element xpath=//div[contains(@class,'tags-container')] + Page Should Contain Element xpath=//ul[contains(@class,'tags-list')] + Page Should Contain Element xpath=//li[contains(@class,'tag-item')] + + # [Check] Back navigation capability + ${back_link_exists}= Run Keyword And Return Status Page Should Contain Element xpath=//a[contains(text(),'Back') or contains(@class,'back')] + + # [Navigate] Back to homepage if link exists + Run Keyword If ${back_link_exists} + ... Run Keywords + ... Click Element xpath=//a[contains(text(),'Back') or contains(@class,'back')] AND + ... Wait Until Location Contains ${HOME URL} AND + ... Wait Until Element Is Visible xpath=//div[contains(@class,'highlight-card')] + + [Teardown] Close Browser + diff --git a/Project/Test/UAT/log.html b/Project/Test/UAT/log.html deleted file mode 100644 index 4879ccde..00000000 --- a/Project/Test/UAT/log.html +++ /dev/null @@ -1,2454 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Opening Robot Framework log failed

- -
- - -
- - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Project/Test/UAT/output.xml b/Project/Test/UAT/output.xml deleted file mode 100644 index 1b7af18f..00000000 --- a/Project/Test/UAT/output.xml +++ /dev/null @@ -1,867 +0,0 @@ - - - - - - -${chrome_options} = <selenium.webdriver.chrome.options.Options object at 0x0000022A950A94E0> -${chrome_options} -sys.modules['selenium.webdriver'].ChromeOptions() -sys -Evaluates the given expression in Python and returns the result. - - - -${chrome_options.binary_location} = C:\xampp\htdocs\git-group-repository-group-2\Project\Test\UAT\ChromeForTesting\chrome.exe -${chrome_options.binary_location} -${CHROME_BROWSER_PATH} -Returns the given values which can then be assigned to a variables. - - - -${chrome_options} -add_argument ---no-sandbox -Calls the named method of the given object with the provided arguments. - - - -${service} = <selenium.webdriver.chrome.service.Service object at 0x0000022A950A9960> -${service} -sys.modules["selenium.webdriver.chrome.service"].Service(executable_path=r"${CHROME_DRIVER_PATH}") -Evaluates the given expression in Python and returns the result. - - - -Creating an instance of the Chrome WebDriver. -Chrome -options=${chrome_options} -service=${service} -Creates an instance of Selenium WebDriver. - - - -Opening url 'http://localhost:8000/login' -${LOGIN URL} -Navigates the current browser window to the provided ``url``. - - - - -Current location is 'http://localhost:8000/login'. -${LOGIN URL} -Verifies that the current URL is exactly ``url``. - - - - - -Maximizes current browser window. - - - - - - -Typing text 'staff@gmail.com' into text field 'id=username'. -id=username -${STAFF_USERNAME} -Types the given ``text`` into the text field identified by ``locator``. - - - -Typing text '123456789' into text field 'id=password'. -id=password -${STAFF_PASSWORD} -Types the given ``text`` into the text field identified by ``locator``. - - - -Slept 2 seconds. -2s -Pauses the test executed for the given time. - - - -Clicking button 'xpath=//button[@type='submit']'. -xpath=//button[@type='submit'] -Clicks the button identified by ``locator``. - - - -Current location is 'http://localhost:8000/dashboard'. -${STAFF URL} -Verifies that the current URL is exactly ``url``. - - - - - -Clicking element 'xpath=//a[contains(@href,'highlight')]'. -xpath=//a[contains(@href,'highlight')] -Click the element identified by ``locator``. - - - -Typing text 'วิทยาลัยการคอมพิวเตอร์ มหาวิทยาลัยขอนแก่น ขอแสดงความยินดีกับ อาจารย์ ดร.เพชร อิ่มทองคำ อาจารย์ประจำวิทยาลัยการคอมพิวเตอร์ เนื่องในโอกาสได้รับแต่งตั้งให้ดำรงตำแหน่ง "ผู้ช่วยศาสตราจารย์"' into text field 'id=title'. -id=title -${TITLE_1} -Types the given ``text`` into the text field identified by ``locator``. - - - -Typing text 'วิทยาลัยการคอมพิวเตอร์ มหาวิทยาลัยขอนแก่น ขอแสดงความยินดีกับ อาจารย์ ดร.เพชร อิ่มทองคำ อาจารย์ประจำวิทยาลัยการคอมพิวเตอร์ เนื่องในโอกาสได้รับแต่งตั้งให้ดำรงตำแหน่ง "ผู้ช่วยศาสตราจารย์" ในสาขาวิชาเทคโนโลยีสารสนเทศตั้งแต่วันที่ 16 พฤษภาคม 2567 ตามที่สภามหาวิทยาลัยขอนแก่นได้มีมติอนุมัติแต่งตั้งให้ดำรงตำแหน่งทางวิชาการในคราวการประชุมครั้งที่ 3/2568 เมื่อวันที่ 5 มีนาคม 2568' into text field 'id=detail'. -id=detail -${DETAIL_1} -Types the given ``text`` into the text field identified by ``locator``. - - - -${IMAGE_PATH} = C:\xampp\htdocs\git-group-repository-group-2\Project\Test\UAT\highlight_image_test01.jpg -${IMAGE_PATH} -${EXECDIR}${/}highlight_image_test01.jpg -Returns the given values which can then be assigned to a variables. - - - -Sending C:\xampp\htdocs\git-group-repository-group-2\Project\Test\UAT\highlight_image_test01.jpg to browser. -id=thumbnail -${IMAGE_PATH} -Inputs the ``file_path`` into the file input field ``locator``. - - - -Slept 2 seconds. -2s -Pauses the test executed for the given time. - - - -${IMAGE_PATH} = C:\xampp\htdocs\git-group-repository-group-2\Project\Test\UAT\highlight_image_test01.jpg -${IMAGE_PATH} -${EXECDIR}${/}highlight_image_test01.jpg -Returns the given values which can then be assigned to a variables. - - - -Sending C:\xampp\htdocs\git-group-repository-group-2\Project\Test\UAT\highlight_image_test01.jpg to browser. -id=additional_thumbnails -${IMAGE_PATH} -Inputs the ``file_path`` into the file input field ``locator``. - - - -Slept 2 seconds. -2s -Pauses the test executed for the given time. - - - -Typing text 'KKU' into text field 'id=tags'. -id=tags -KKU -Types the given ``text`` into the text field identified by ``locator``. - - - -Sending key(s) ('ENTER',) to id=tags element. -Pressing special key ENTER to element. -Releasing special key ENTER. -id=tags -ENTER -Simulates the user pressing key(s) to an element or on the active browser. - - - -Typing text 'มข.' into text field 'id=tags'. -id=tags -มข. -Types the given ``text`` into the text field identified by ``locator``. - - - -Sending key(s) ('ENTER',) to id=tags element. -Pressing special key ENTER to element. -Releasing special key ENTER. -id=tags -ENTER -Simulates the user pressing key(s) to an element or on the active browser. - - - -Typing text 'cpkku' into text field 'id=tags'. -id=tags -cpkku -Types the given ``text`` into the text field identified by ``locator``. - - - -Sending key(s) ('ENTER',) to id=tags element. -Pressing special key ENTER to element. -Releasing special key ENTER. -id=tags -ENTER -Simulates the user pressing key(s) to an element or on the active browser. - - - -Typing text 'computing' into text field 'id=tags'. -id=tags -computing -Types the given ``text`` into the text field identified by ``locator``. - - - -Sending key(s) ('ENTER',) to id=tags element. -Pressing special key ENTER to element. -Releasing special key ENTER. -id=tags -ENTER -Simulates the user pressing key(s) to an element or on the active browser. - - - -Typing text 'phet' into text field 'id=tags'. -id=tags -phet -Types the given ``text`` into the text field identified by ``locator``. - - - -Sending key(s) ('ENTER',) to id=tags element. -Pressing special key ENTER to element. -Releasing special key ENTER. -id=tags -ENTER -Simulates the user pressing key(s) to an element or on the active browser. - - - -Slept 2 seconds. -2s -Pauses the test executed for the given time. - - - -Executing JavaScript: -document.querySelector("button.btn-primary").scrollIntoView({behavior: "smooth", block: "center"}); -Without any arguments. -document.querySelector("button.btn-primary").scrollIntoView({behavior: "smooth", block: "center"}); -Executes the given JavaScript code with possible arguments. - - - -Slept 1 second. -1s -Pauses the test executed for the given time. - - - -xpath=//button[contains(.,'Upload')] -Waits until the element ``locator`` is visible. - - - -xpath=//button[contains(.,'Upload')] -Waits until the element ``locator`` is enabled. - - - -Executing JavaScript: -document.querySelector("button[type='submit']").click(); -Without any arguments. -document.querySelector("button[type='submit']").click(); -Executes the given JavaScript code with possible arguments. - - - -Slept 2 seconds. -2s -Pauses the test executed for the given time. - - - -${highlight_count} = 1 -${highlight_count} -xpath=//a[contains(@href,'highlights') and contains(@class,'btn-outline-success')] -Returns the number of elements matching ``locator``. - - - -Found 1 highlights -Found ${highlight_count} highlights -Logs the given message with the given level. - - - -Slept 2 seconds. -2s -Pauses the test executed for the given time. - - - -xpath=(//a[contains(@href,'highlights') and contains(@class,'btn-outline-primary')])[${highlight_count}] -Waits until the element ``locator`` is visible. - - - -Clicking element 'xpath=(//a[contains(@href,'highlights') and contains(@class,'btn-outline-primary')])[1]'. -xpath=(//a[contains(@href,'highlights') and contains(@class,'btn-outline-primary')])[${highlight_count}] -Click the element identified by ``locator``. - - - -Slept 2 seconds. -2s -Pauses the test executed for the given time. - - - -${TITLE_1} -Waits until ``text`` appears on the current page. - - - -${DETAIL_1} -Waits until ``text`` appears on the current page. - - - -xpath=//a[contains(text(),'Back')] -Waits until the element ``locator`` is visible. - - - -Clicking element 'xpath=//a[contains(text(),'Back')]'. -xpath=//a[contains(text(),'Back')] -Click the element identified by ``locator``. - - - - -xpath=//a[contains(text(),'Logout')] -Waits until the element ``locator`` is visible. - - - -Clicking element 'xpath=//a[contains(text(),'Logout')]'. -xpath=//a[contains(text(),'Logout')] -Click the element identified by ``locator``. - - - - - -Closes all open browsers and resets the browser cache. - - -UAT001-CheckHighlightDetail - - - - - -${chrome_options} = <selenium.webdriver.chrome.options.Options object at 0x0000022A9511CAF0> -${chrome_options} -sys.modules['selenium.webdriver'].ChromeOptions() -sys -Evaluates the given expression in Python and returns the result. - - - -${chrome_options.binary_location} = C:\xampp\htdocs\git-group-repository-group-2\Project\Test\UAT\ChromeForTesting\chrome.exe -${chrome_options.binary_location} -${CHROME_BROWSER_PATH} -Returns the given values which can then be assigned to a variables. - - - -${chrome_options} -add_argument ---no-sandbox -Calls the named method of the given object with the provided arguments. - - - -${service} = <selenium.webdriver.chrome.service.Service object at 0x0000022A9511C580> -${service} -sys.modules["selenium.webdriver.chrome.service"].Service(executable_path=r"${CHROME_DRIVER_PATH}") -Evaluates the given expression in Python and returns the result. - - - -Creating an instance of the Chrome WebDriver. -Chrome -options=${chrome_options} -service=${service} -Creates an instance of Selenium WebDriver. - - - -Opening url 'http://localhost:8000/login' -${LOGIN URL} -Navigates the current browser window to the provided ``url``. - - - - -Current location is 'http://localhost:8000/login'. -${LOGIN URL} -Verifies that the current URL is exactly ``url``. - - - - - -Maximizes current browser window. - - - - - - -Typing text 'staff@gmail.com' into text field 'id=username'. -id=username -${STAFF_USERNAME} -Types the given ``text`` into the text field identified by ``locator``. - - - -Typing text '123456789' into text field 'id=password'. -id=password -${STAFF_PASSWORD} -Types the given ``text`` into the text field identified by ``locator``. - - - -Slept 2 seconds. -2s -Pauses the test executed for the given time. - - - -Clicking button 'xpath=//button[@type='submit']'. -xpath=//button[@type='submit'] -Clicks the button identified by ``locator``. - - - -Current location is 'http://localhost:8000/dashboard'. -${STAFF URL} -Verifies that the current URL is exactly ``url``. - - - - - -Clicking element 'xpath=//a[contains(@href,'highlight')]'. -xpath=//a[contains(@href,'highlight')] -Click the element identified by ``locator``. - - - -xpath=//a[contains(text(),'Manage Highlight')] -Waits until the element ``locator`` is visible. - - - -Clicking element 'xpath=//a[contains(text(),'Manage Highlight')]'. -xpath=//a[contains(text(),'Manage Highlight')] -Click the element identified by ``locator``. - - - -${highlight_count} = 1 -${highlight_count} -xpath=//a[contains(@href,'highlights') and contains(@class,'btn-outline-success')] -Returns the number of elements matching ``locator``. - - - -Found 1 highlights -Found ${highlight_count} highlights -Logs the given message with the given level. - - - -xpath=(//a[contains(@href,'highlights') and contains(@class,'btn-outline-success')])[${highlight_count}] -Waits until the element ``locator`` is visible. - - - -Clicking element 'xpath=(//a[contains(@href,'highlights') and contains(@class,'btn-outline-success')])[1]'. -xpath=(//a[contains(@href,'highlights') and contains(@class,'btn-outline-success')])[${highlight_count}] -Click the element identified by ``locator``. - - - -Typing text 'นักวิจัย มข. และบริษัทมิตรผล จับมือนำ AI คัดแยกพันธุ์อ้อยสู่เวทีนานาชาติ ในงาน ITEX 2025' into text field 'name=title'. -name=title -${TITLE_2} -Types the given ``text`` into the text field identified by ``locator``. - - - -Typing text 'วิทยาลัยการคอมพิวเตอร์ มหาวิทยาลัยขอนแก่น ขอแสดงความยินดีกับ รศ. ดร.วรารัตน์ สงฆ์แป้น และคณะทีมวิจัย จากบริษัท มิตรผลวิจัย พัฒนาอ้อยและน้ำตาล จำกัด ในผลงานเรื่อง“การพัฒนาแบบจำลองปัญญาประดิษฐ์การคัดแยกพันธุ์อ้อยด้วยการเรียนรู้เครื่องและการเรียนรู้เชิงลึก"' into text field 'name=detail'. -name=detail -${DETAIL_2} -Types the given ``text`` into the text field identified by ``locator``. - - - -${IMAGE_PATH} = C:\xampp\htdocs\git-group-repository-group-2\Project\Test\UAT\highlight_image_test02.jpg -${IMAGE_PATH} -${EXECDIR}${/}highlight_image_test02.jpg -Returns the given values which can then be assigned to a variables. - - - -Sending C:\xampp\htdocs\git-group-repository-group-2\Project\Test\UAT\highlight_image_test02.jpg to browser. -name=thumbnails[] -${IMAGE_PATH} -Inputs the ``file_path`` into the file input field ``locator``. - - - -Typing text 'KKU,มข.,cpkku,cp,ITEX2025' into text field 'name=tags'. -name=tags -KKU,มข.,cpkku,cp,ITEX2025 -Types the given ``text`` into the text field identified by ``locator``. - - - -xpath=//button[@type='submit' and contains(@class,'btn-primary')] -Waits until the element ``locator`` is visible. - - - -Executing JavaScript: -document.querySelector("button[type='submit'].btn-primary").scrollIntoView({behavior: "smooth", block: "center"}); -Without any arguments. -document.querySelector("button[type='submit'].btn-primary").scrollIntoView({behavior: "smooth", block: "center"}); -Executes the given JavaScript code with possible arguments. - - - -Slept 1 second. -1s -Pauses the test executed for the given time. - - - -Executing JavaScript: -document.querySelector("button[type='submit'].btn-primary").click(); -Without any arguments. -document.querySelector("button[type='submit'].btn-primary").click(); -Executes the given JavaScript code with possible arguments. - - - -Slept 3 seconds. -3s -Pauses the test executed for the given time. - - - -Opening url 'http://localhost:8000/highlight/view' -${HIGHLIGHT URL}/view -Navigates the current browser window to the provided ``url``. - - - -Slept 2 seconds. -2s -Pauses the test executed for the given time. - - - -${highlight_count} = 1 -${highlight_count} -xpath=//a[contains(@href,'highlights') and contains(@class,'btn-outline-success')] -Returns the number of elements matching ``locator``. - - - -Found 1 highlights -Found ${highlight_count} highlights -Logs the given message with the given level. - - - -xpath=(//a[contains(@href,'highlights') and contains(@class,'btn-outline-primary')])[${highlight_count}] -Waits until the element ``locator`` is visible. - - - -Clicking element 'xpath=(//a[contains(@href,'highlights') and contains(@class,'btn-outline-primary')])[1]'. -xpath=(//a[contains(@href,'highlights') and contains(@class,'btn-outline-primary')])[${highlight_count}] -Click the element identified by ``locator``. - - - -${TITLE_2} -Waits until ``text`` appears on the current page. - - - -${DETAIL_2} -Waits until ``text`` appears on the current page. - - - -${TITLE_2} -Waits until ``text`` appears on the current page. - - - -${DETAIL_2} -Waits until ``text`` appears on the current page. - - - - -xpath=//a[contains(text(),'Logout')] -Waits until the element ``locator`` is visible. - - - -Clicking element 'xpath=//a[contains(text(),'Logout')]'. -xpath=//a[contains(text(),'Logout')] -Click the element identified by ``locator``. - - - - - -Closes all open browsers and resets the browser cache. - - -UAT004-EditHighlight - - - - - -${chrome_options} = <selenium.webdriver.chrome.options.Options object at 0x0000022A95144BE0> -${chrome_options} -sys.modules['selenium.webdriver'].ChromeOptions() -sys -Evaluates the given expression in Python and returns the result. - - - -${chrome_options.binary_location} = C:\xampp\htdocs\git-group-repository-group-2\Project\Test\UAT\ChromeForTesting\chrome.exe -${chrome_options.binary_location} -${CHROME_BROWSER_PATH} -Returns the given values which can then be assigned to a variables. - - - -${chrome_options} -add_argument ---no-sandbox -Calls the named method of the given object with the provided arguments. - - - -${service} = <selenium.webdriver.chrome.service.Service object at 0x0000022A95144A90> -${service} -sys.modules["selenium.webdriver.chrome.service"].Service(executable_path=r"${CHROME_DRIVER_PATH}") -Evaluates the given expression in Python and returns the result. - - - -Creating an instance of the Chrome WebDriver. -Chrome -options=${chrome_options} -service=${service} -Creates an instance of Selenium WebDriver. - - - -Opening url 'http://localhost:8000/login' -${LOGIN URL} -Navigates the current browser window to the provided ``url``. - - - - -Current location is 'http://localhost:8000/login'. -${LOGIN URL} -Verifies that the current URL is exactly ``url``. - - - - - -Maximizes current browser window. - - - - - - -Typing text 'staff@gmail.com' into text field 'id=username'. -id=username -${STAFF_USERNAME} -Types the given ``text`` into the text field identified by ``locator``. - - - -Typing text '123456789' into text field 'id=password'. -id=password -${STAFF_PASSWORD} -Types the given ``text`` into the text field identified by ``locator``. - - - -Slept 2 seconds. -2s -Pauses the test executed for the given time. - - - -Clicking button 'xpath=//button[@type='submit']'. -xpath=//button[@type='submit'] -Clicks the button identified by ``locator``. - - - -Current location is 'http://localhost:8000/dashboard'. -${STAFF URL} -Verifies that the current URL is exactly ``url``. - - - - - -Clicking element 'xpath=//a[contains(@href,'highlight')]'. -xpath=//a[contains(@href,'highlight')] -Click the element identified by ``locator``. - - - -xpath=//a[contains(text(),'Manage Highlight')] -Waits until the element ``locator`` is visible. - - - -Clicking element 'xpath=//a[contains(text(),'Manage Highlight')]'. -xpath=//a[contains(text(),'Manage Highlight')] -Click the element identified by ``locator``. - - - -${highlight_count} = 1 -${highlight_count} -xpath=//a[contains(@href,'highlights') and contains(@class,'btn-outline-success')] -Returns the number of elements matching ``locator``. - - - -Found 1 highlights -Found ${highlight_count} highlights -Logs the given message with the given level. - - - -xpath=(//button[contains(@class,'btn-outline-danger') or contains(@class,'show_confirm')])[${highlight_count}] -Waits until the element ``locator`` is visible. - - - -Executing JavaScript: -document.querySelector("button.show_confirm").click(); -Without any arguments. -document.querySelector("button.show_confirm").click(); -Executes the given JavaScript code with possible arguments. - - - -xpath=//div[contains(@class,'swal-modal')] -Waits until the element ``locator`` is visible. - - - -xpath=//button[contains(@class,'swal-button--confirm')] -Waits until the element ``locator`` is visible. - - - -Clicking element 'xpath=//button[contains(@class,'swal-button--confirm')]'. -xpath=//button[contains(@class,'swal-button--confirm')] -Click the element identified by ``locator``. - - - -Slept 3 seconds. -3s -Pauses the test executed for the given time. - - - -xpath=//div[contains(@class,'swal-modal')] -Waits until the element ``locator`` is visible. - - - -xpath=//div[contains(text(),'Deleted Successfully')] -Waits until the element ``locator`` is visible. - - - -xpath=//button[contains(@class,'swal-button--confirm')] -Waits until the element ``locator`` is visible. - - - -Clicking element 'xpath=//button[contains(@class,'swal-button--confirm')]'. -xpath=//button[contains(@class,'swal-button--confirm')] -Click the element identified by ``locator``. - - - -Slept 2 seconds. -2s -Pauses the test executed for the given time. - - - - -xpath=//a[contains(text(),'Logout')] -Waits until the element ``locator`` is visible. - - - -Clicking element 'xpath=//a[contains(text(),'Logout')]'. -xpath=//a[contains(text(),'Logout')] -Click the element identified by ``locator``. - - - - - -Closes all open browsers and resets the browser cache. - - -UAT004-DeleteHighlight - - - - - - -All Tests - - -UAT001-CheckHighlightDetail -UAT004-DeleteHighlight -UAT004-EditHighlight - - -UAT Highlight Staff - - - - - diff --git a/Project/Test/UAT/report.html b/Project/Test/UAT/report.html deleted file mode 100644 index 10429ba9..00000000 --- a/Project/Test/UAT/report.html +++ /dev/null @@ -1,2735 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Opening Robot Framework report failed

- -
- -
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -