使用場景
本樣例用於在給定的HTML檔案中(簡單的登入註冊),測試多組賬號密碼是否能夠成功登入,並列印出登入結果。
前端程式碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login Page</title>
<script>
// 定義登入函式
function login() {
// 獲取使用者名稱和密碼
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
var resultDiv = document.getElementById("login-result");
// 檢查使用者名稱和密碼(此示例中為了簡單,直接使用靜態的使用者名稱和密碼)
if(username === "admin" && password === "password") {
// 登入成功
resultDiv.innerText = "登入成功!";
resultDiv.style.color = "green";
} else {
// 登入失敗
resultDiv.innerText = "登入失敗:使用者名稱或密碼錯誤。";
resultDiv.style.color = "red";
}
// 防止表單實際提交
return false;
}
</script>
</head>
<body>
<h2>登入頁面</h2>
<!-- 建立登入表單 -->
<form onsubmit="return login();">
<label for="username">使用者名稱:</label><br>
<input type="text" id="username" name="username" required><br>
<label for="password">密碼:</label><br>
<input type="password" id="password" name="password" required><br><br>
<input type="submit" value="登入">
</form>
<!-- 新增一個元素用來顯示登入結果 -->
<div id="login-result"></div>
</body>
</html>
這是一個最簡單的登入表單,使用者進行提交時,在id
為login-result
的元素中顯示登入的結果。
後端程式碼
package main
import (
"fmt"
"github.com/go-rod/rod"
"time"
)
// 測試的賬號密碼組
var credentials = []struct {
Username string
Password string
}{
{"admin", "password"}, // 應該成功
{"user", "123456"}, // 應該失敗
{"admin", "wrongpass"}, // 應該失敗
// 可以新增更多的測試組
}
func main() {
browser := rod.New().MustConnect().MustPage()
defer browser.MustClose()
for _, cred := range credentials {
testLogin(browser, cred.Username, cred.Password)
time.Sleep(1 * time.Second) // 給頁面一些時間來處理登入並顯示結果
}
}
func testLogin(page *rod.Page, username, password string) {
page.MustNavigate("http://localhost:63344/LoginTese/LoginTese/login.html")
page.MustElement("#username").MustInput(username)
page.MustElement("#password").MustInput(password)
page.MustElement("input[type='submit']").MustClick()
// 假設登入結果會顯示在id為"login-result"的元素中
// 使用Racer來等待頁面載入或者特定元素出現
resultSelector := "#login-result"
page.Race().Element(resultSelector).MustHandle(func(e *rod.Element) {
resultText, err := e.Text()
if err != nil {
fmt.Println("Error getting result text:", err)
return
}
fmt.Printf("Login result for '%s': %s\n", username, resultText)
}).MustDo()
// 可以根據需要調整等待時間
time.Sleep(2 * time.Second)
}
我們詳細來看一下後端程式碼,由於是剛剛入門,我們把每一行程式碼詳細地分析一下,方便日後再次使用。
var credentials = []struct {
Username string
Password string
}{
{"admin", "password"}, // 應該成功
{"user", "123456"}, // 應該失敗
{"admin", "wrongpass"}, // 應該失敗
// 可以新增更多的測試組
}
- 這段 Go 語言的程式碼定義了一個名為
credentials
的變數,它是一個由結構體組成的切片。每個結構體包含兩個欄位:Username
和Password
,分別代表登入所需的使用者名稱和密碼。 - 變數定義、結構體定義比較好理解,這裡不展開說了,我們著重說一下切片初始化。
[]struct{...}{...}
這部分不僅宣告瞭一個結構體切片型別,還透過{...}
對其進行了初始化。切片中的每個元素都是透過{}
來初始化,其中Username
和Password
欄位被賦予相應的值。
browser := rod.New().MustConnect().MustPage()
defer browser.MustClose()
啟動瀏覽器程式建立連線,確保程式終止前執行關閉,沒有什麼可以細說的。
for _, cred := range credentials {
testLogin(browser, cred.Username, cred.Password)
time.Sleep(1 * time.Second) // 給頁面一些時間來處理登入並顯示結果
}
- 遍歷
credentials
,傳入瀏覽器、使用者名稱、密碼三個引數,執行testLogin
函式進行測試。 - 在頁面稍做停留,給頁面時間來處理並顯示結果。
func testLogin(page *rod.Page, username, password string) {
page.MustNavigate("http://localhost:63344/LoginTese/LoginTese/login.html")
page.MustElement("#username").MustInput(username)
page.MustElement("#password").MustInput(password)
page.MustElement("input[type='submit']").MustClick()
// 假設登入結果會顯示在id為"login-result"的元素中
// 使用Racer來等待頁面載入或者特定元素出現
resultSelector := "#login-result"
page.Race().Element(resultSelector).MustHandle(func(e *rod.Element) {
resultText, err := e.Text()
if err != nil {
fmt.Println("Error getting result text:", err)
return
}
fmt.Printf("Login result for '%s': %s\n", username, resultText)
}).MustDo()
// 可以根據需要調整等待時間
time.Sleep(2 * time.Second)
}
- 來看一下
testLogin
內的內容page.MustNavigate("http://localhost:63344/LoginTese/LoginTese/login.html"):
導航瀏覽器到提供的URL地址。page.MustElement("#username").MustInput(username):
在id為username
的元素內傳入username的值。page.MustElement("#password").MustInput(password):
在id為password
的元素哪傳入password的值。page.MustElement("input[type='submit']").MustClick():
尋找第一個type
為submit
的input
元素,並點選它。page.Race()
建立了一個競態條件(race condition),在這個條件下,多個事件或元素被並行等待。Race
是 go-rod 庫中的一個功能,允許開發者定義一系列可能發生的事件,然後執行與首個發生的事件相關的回撥函式。.Element(resultSelector)
是Race
的一個方法,用於指定一個 CSS 選擇器來尋找頁面上的元素。resultSelector
是一個字串變數,其中包含了 CSS 選擇器的值。這個選擇器用來找到顯示登入結果的元素。.MustHandle(func(e *rod.Element))
為找到的元素定義了一個處理函式。如果元素被成功找到,這個處理函式將被呼叫。在這個處理函式中,e
是指向找到的元素的指標。- 在處理函式內部,
e.Text()
被呼叫來獲取元素的文字內容。這個文字內容預期包含登入的結果(例如,“登入成功”或“登入失敗:使用者名稱或密碼錯誤”)。 .MustDo()
是必須呼叫的方法,它觸發了前面定義的Race
條件的執行。沒有這個呼叫,之前設定的等待條件和處理函式都不會被實際執行。