使用场景
本样例用于在给定的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
条件的执行。没有这个调用,之前设置的等待条件和处理函数都不会被实际执行。