|
|
|
|
|
namespace PlaywrightStudy.Test
|
|
|
{
|
|
|
public class PlaywrightTest
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 通过 API 安装浏览器
|
|
|
/// 当然有多种安装方式
|
|
|
/// </summary>
|
|
|
[Fact]
|
|
|
public void Install_Browsers_Test()
|
|
|
{
|
|
|
var exitCode = Microsoft.Playwright.Program.Main(new[] { "install" });
|
|
|
if (exitCode != 0)
|
|
|
{
|
|
|
throw new Exception($"Playwright exited with code {exitCode}");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#region Edge
|
|
|
[Fact]
|
|
|
public async void Baidu_Edge_Test()
|
|
|
{
|
|
|
using var playwright = await Playwright.CreateAsync();
|
|
|
|
|
|
//await using var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions()
|
|
|
//{
|
|
|
// SlowMo = 50, //慢速
|
|
|
// Headless = false, // 关闭无头模式(有界面)
|
|
|
// Channel = "msedge", // 指定采用chrome浏览器类型()
|
|
|
// Devtools = false, // 启用开发者工具
|
|
|
// ChromiumSandbox = false, // 关闭浏览器沙盒
|
|
|
// ExecutablePath = string.Empty, // 不指定浏览器可执行文件位置,会自动寻找 ms-playwright 下载的浏览器
|
|
|
// Args = new[] { "--enable-automation=true", "--disable-blink-features=AutomationControlled" }, // 防止selenium被检测
|
|
|
//});
|
|
|
|
|
|
//浏览器:默认Edge优先
|
|
|
await using var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions()
|
|
|
{
|
|
|
//关闭无头模式(有界面)
|
|
|
Headless = false,
|
|
|
});
|
|
|
|
|
|
//浏览器上下文
|
|
|
var browserContexts = browser.Contexts;
|
|
|
|
|
|
//页面
|
|
|
var page = await browser.NewPageAsync();
|
|
|
|
|
|
//页面响应
|
|
|
var response = await page.GotoAsync("https://www.baidu.com/");
|
|
|
|
|
|
//定位器:搜索框
|
|
|
var searchBoxLocator = page.GetByRole(AriaRole.Textbox).Nth(0);
|
|
|
|
|
|
//元素个数
|
|
|
var count = await searchBoxLocator.CountAsync();
|
|
|
|
|
|
//xUnit断言
|
|
|
Assert.True(count > 0);
|
|
|
|
|
|
//Playwright断言
|
|
|
await Microsoft.Playwright.Assertions.Expect(searchBoxLocator).ToHaveCountAsync(1);
|
|
|
|
|
|
//输入搜索内容前部分(一次性全部输入)
|
|
|
await searchBoxLocator.FillAsync("Playwright");
|
|
|
|
|
|
//输入搜索内容后部分(模拟用户输入:每个字符之间有延时),已弃用
|
|
|
//await textboxLocator.TypeAsync(".net", new LocatorTypeOptions { Delay = 1000 });
|
|
|
|
|
|
//输入搜索内容后部分(模拟用户输入:每个字符之间有延时)
|
|
|
await searchBoxLocator.PressSequentiallyAsync(".NET", new LocatorPressSequentiallyOptions { Delay = 200 });
|
|
|
|
|
|
//输入回车:确认搜索[可输入特殊字符,也可以是组合键("Shift+Home"、"Alt+Enter")]
|
|
|
//await searchBoxLocator.PressAsync("Enter");
|
|
|
|
|
|
//方法二:单击搜索按钮
|
|
|
var searchButtonLocator = page.Locator("#su");
|
|
|
|
|
|
var searchButtonCount = await searchButtonLocator.CountAsync();
|
|
|
|
|
|
//断言:按钮找到
|
|
|
await Microsoft.Playwright.Assertions.Expect(searchButtonLocator).ToHaveCountAsync(1);
|
|
|
|
|
|
//单击搜索按钮
|
|
|
await searchButtonLocator.ClickAsync();
|
|
|
|
|
|
//使用 page.Keyboard 和 page.Mouse 对象来模拟键盘和鼠标的操作
|
|
|
//await page.Keyboard.PressAsync("Enter");
|
|
|
//await page.Mouse.ClickAsync(100, 100);
|
|
|
|
|
|
await page.WaitForLoadStateAsync();
|
|
|
|
|
|
//页面截图
|
|
|
await page.ScreenshotAsync(new()
|
|
|
{
|
|
|
Path = "Baidu.Edge.Screenshot.png",
|
|
|
FullPage = true, //整页截图
|
|
|
});
|
|
|
|
|
|
//元素截图
|
|
|
var paggerLocator = page.Locator("#page");
|
|
|
|
|
|
//无此行,则元素截图错误
|
|
|
var paagerCount = await paggerLocator.CountAsync();
|
|
|
|
|
|
await paggerLocator.ScreenshotAsync(new LocatorScreenshotOptions()
|
|
|
{
|
|
|
Path = "Baidu.Edge.ByPage.Screenshot.png",
|
|
|
//Quality = 100,
|
|
|
Type = ScreenshotType.Png
|
|
|
});
|
|
|
|
|
|
//网页保存为Pdf文件
|
|
|
await page.PdfAsync(new()
|
|
|
{
|
|
|
Path = "Baidu.Edge.pdf",
|
|
|
DisplayHeaderFooter = false,
|
|
|
Format = "A4"
|
|
|
});
|
|
|
}
|
|
|
|
|
|
[Fact]
|
|
|
public async void Bing_Edge_Test()
|
|
|
{
|
|
|
using var playwright = await Playwright.CreateAsync();
|
|
|
|
|
|
//浏览器:默认Edge优先
|
|
|
await using var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions()
|
|
|
{
|
|
|
//关闭无头模式(有界面)
|
|
|
Headless = false,
|
|
|
});
|
|
|
|
|
|
//浏览器上下文
|
|
|
var browserContexts = browser.Contexts;
|
|
|
|
|
|
//页面
|
|
|
var page = await browser.NewPageAsync();
|
|
|
|
|
|
//页面响应
|
|
|
var response = await page.GotoAsync("https://cn.bing.com/");
|
|
|
|
|
|
//请求成功
|
|
|
Assert.Equal(200, response?.Status);
|
|
|
|
|
|
//定位器:搜索框
|
|
|
var searchBoxLocator = page.Locator("input#sb_form_q");
|
|
|
|
|
|
//输入框个数
|
|
|
var count = await searchBoxLocator.CountAsync();
|
|
|
|
|
|
//xUnit断言
|
|
|
Assert.True(count > 0);
|
|
|
|
|
|
//Playwright断言
|
|
|
await Microsoft.Playwright.Assertions.Expect(searchBoxLocator).ToHaveCountAsync(1);
|
|
|
|
|
|
//输入搜索内容前部分(一次性全部输入)
|
|
|
//await searchBoxLocator.FillAsync("Playwright");
|
|
|
|
|
|
//输入搜索内容后部分(模拟用户输入:每个字符之间有延时)
|
|
|
await searchBoxLocator.PressSequentiallyAsync("Playwright.NET", new LocatorPressSequentiallyOptions { Delay = 200 });
|
|
|
|
|
|
//输入回车:确认搜索[可输入特殊字符,也可以是组合键("Shift+Home"、"Alt+Enter")]
|
|
|
await searchBoxLocator.PressAsync("Enter");
|
|
|
|
|
|
await page.WaitForLoadStateAsync();
|
|
|
|
|
|
//截图
|
|
|
await page.ScreenshotAsync(new()
|
|
|
{
|
|
|
Path = "Bing.Edge.Screenshot.png"
|
|
|
});
|
|
|
|
|
|
//网页保存为Pdf文件
|
|
|
await page.PdfAsync(new()
|
|
|
{
|
|
|
Path = "Bing.Edge.pdf",
|
|
|
DisplayHeaderFooter = false,
|
|
|
Format = "A4"
|
|
|
});
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region Chrome
|
|
|
|
|
|
/// <summary>
|
|
|
/// 比较详细
|
|
|
/// </summary>
|
|
|
[Fact]
|
|
|
public async void Baidu_Chrome_Test()
|
|
|
{
|
|
|
using var playwright = await Playwright.CreateAsync();
|
|
|
|
|
|
//浏览器:指定 chrome
|
|
|
await using var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions()
|
|
|
{
|
|
|
SlowMo = 50, //慢速
|
|
|
Headless = false, // 关闭无头模式(有界面)
|
|
|
Channel = "chrome", // 指定采用chrome浏览器类型()
|
|
|
Devtools = false, // 启用开发者工具
|
|
|
ChromiumSandbox = true, // 关闭浏览器沙盒
|
|
|
ExecutablePath = string.Empty, // 不指定浏览器可执行文件位置,会自动寻找 ms-playwright 下载的浏览器
|
|
|
DownloadsPath = "download",
|
|
|
});
|
|
|
|
|
|
//页面
|
|
|
var page = await browser.NewPageAsync();
|
|
|
|
|
|
//页面响应
|
|
|
var response = await page.GotoAsync("https://www.baidu.com/");
|
|
|
|
|
|
//定位器:搜索框
|
|
|
var searchBoxLocator = page.GetByRole(AriaRole.Textbox).Nth(0);
|
|
|
|
|
|
//元素个数
|
|
|
var count = await searchBoxLocator.CountAsync();
|
|
|
|
|
|
//xUnit断言
|
|
|
Assert.True(count > 0);
|
|
|
|
|
|
//Playwright断言
|
|
|
await Microsoft.Playwright.Assertions.Expect(searchBoxLocator).ToHaveCountAsync(1);
|
|
|
|
|
|
//输入搜索内容前部分(一次性全部输入)
|
|
|
//await searchBoxLocator.FillAsync("Playwright");
|
|
|
|
|
|
//输入搜索内容后部分(模拟用户输入:每个字符之间有延时)
|
|
|
await searchBoxLocator.PressSequentiallyAsync("Playwright.NET", new LocatorPressSequentiallyOptions { Delay = 200 });
|
|
|
|
|
|
//输入回车:确认搜索[可输入特殊字符,也可以是组合键("Shift+Home"、"Alt+Enter")]
|
|
|
await searchBoxLocator.PressAsync("Enter");
|
|
|
|
|
|
//等待
|
|
|
await page.WaitForLoadStateAsync(LoadState.DOMContentLoaded);
|
|
|
|
|
|
//截图
|
|
|
await page.ScreenshotAsync(new()
|
|
|
{
|
|
|
Path = "Baidu.Chrome.Screenshot.png"
|
|
|
});
|
|
|
|
|
|
//网页保存为Pdf文件
|
|
|
await page.PdfAsync(new()
|
|
|
{
|
|
|
Path = "Baidu.Chrome.pdf",
|
|
|
DisplayHeaderFooter = false,
|
|
|
Format = "A4"
|
|
|
});
|
|
|
}
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region Firefox
|
|
|
[Fact]
|
|
|
public async void Baidu_Firefox_Test()
|
|
|
{
|
|
|
using var playwright = await Playwright.CreateAsync();
|
|
|
|
|
|
//浏览器:指定 chrome
|
|
|
await using var browser = await playwright.Firefox.LaunchAsync(new BrowserTypeLaunchOptions()
|
|
|
{
|
|
|
SlowMo = 50, //慢速
|
|
|
Headless = false, // 关闭无头模式(有界面
|
|
|
Devtools = false, // 启用开发者工具
|
|
|
ChromiumSandbox = true, // 关闭浏览器沙盒
|
|
|
ExecutablePath = string.Empty, // 不指定浏览器可执行文件位置,会自动寻找 ms-playwright 下载的浏览器
|
|
|
DownloadsPath = "download",
|
|
|
});
|
|
|
|
|
|
//页面
|
|
|
var page = await browser.NewPageAsync();
|
|
|
|
|
|
//页面响应
|
|
|
var response = await page.GotoAsync("https://www.baidu.com/");
|
|
|
|
|
|
//定位器:搜索框
|
|
|
var searchBoxLocator = page.GetByRole(AriaRole.Textbox).Nth(0);
|
|
|
|
|
|
//元素个数
|
|
|
var count = await searchBoxLocator.CountAsync();
|
|
|
|
|
|
//xUnit断言
|
|
|
Assert.True(count > 0);
|
|
|
|
|
|
//Playwright断言
|
|
|
await Microsoft.Playwright.Assertions.Expect(searchBoxLocator).ToHaveCountAsync(1);
|
|
|
|
|
|
//输入搜索内容前部分(一次性全部输入)
|
|
|
//await searchBoxLocator.FillAsync("Playwright");
|
|
|
|
|
|
//输入搜索内容后部分(模拟用户输入:每个字符之间有延时)
|
|
|
await searchBoxLocator.PressSequentiallyAsync("Playwright.NET", new LocatorPressSequentiallyOptions { Delay = 200 });
|
|
|
|
|
|
//输入回车:确认搜索[可输入特殊字符,也可以是组合键("Shift+Home"、"Alt+Enter")]
|
|
|
await searchBoxLocator.PressAsync("Enter");
|
|
|
|
|
|
//等待
|
|
|
await page.WaitForLoadStateAsync(LoadState.DOMContentLoaded);
|
|
|
|
|
|
//截图
|
|
|
await page.ScreenshotAsync(new()
|
|
|
{
|
|
|
Path = "Baidu.Firefox.Screenshot.png"
|
|
|
});
|
|
|
|
|
|
//网页保存为Pdf文件:FireFox不支持
|
|
|
//await page.PdfAsync(new()
|
|
|
//{
|
|
|
// Path = "Baidu.Firefox.pdf",
|
|
|
// DisplayHeaderFooter = false,
|
|
|
// Format = "A4"
|
|
|
//});
|
|
|
}
|
|
|
|
|
|
[Fact]
|
|
|
public async void Bing_Firefox_Test()
|
|
|
{
|
|
|
using var playwright = await Playwright.CreateAsync();
|
|
|
|
|
|
//浏览器:指定 chrome
|
|
|
await using var browser = await playwright.Firefox.LaunchAsync(new BrowserTypeLaunchOptions()
|
|
|
{
|
|
|
SlowMo = 50, //慢速
|
|
|
Headless = false, // 关闭无头模式(有界面
|
|
|
Devtools = false, // 启用开发者工具
|
|
|
ChromiumSandbox = true, // 关闭浏览器沙盒
|
|
|
ExecutablePath = string.Empty, // 不指定浏览器可执行文件位置,会自动寻找 ms-playwright 下载的浏览器
|
|
|
DownloadsPath = "download",
|
|
|
});
|
|
|
|
|
|
//浏览器上下文
|
|
|
var browserContexts = browser.Contexts;
|
|
|
|
|
|
//页面
|
|
|
var page = await browser.NewPageAsync();
|
|
|
|
|
|
//页面响应
|
|
|
var response = await page.GotoAsync("https://cn.bing.com/");
|
|
|
|
|
|
//请求成功
|
|
|
Assert.Equal(200, response?.Status);
|
|
|
|
|
|
//定位器:搜索框
|
|
|
var searchBoxLocator = page.Locator("input#sb_form_q");
|
|
|
|
|
|
//输入框个数
|
|
|
var count = await searchBoxLocator.CountAsync();
|
|
|
|
|
|
//xUnit断言
|
|
|
Assert.True(count > 0);
|
|
|
|
|
|
//Playwright断言
|
|
|
await Microsoft.Playwright.Assertions.Expect(searchBoxLocator).ToHaveCountAsync(1);
|
|
|
|
|
|
//输入搜索内容前部分(一次性全部输入)
|
|
|
//await searchBoxLocator.FillAsync("Playwright");
|
|
|
|
|
|
//输入搜索内容后部分(模拟用户输入:每个字符之间有延时)
|
|
|
await searchBoxLocator.PressSequentiallyAsync("Playwright.NET", new LocatorPressSequentiallyOptions { Delay = 200 });
|
|
|
|
|
|
//输入回车:确认搜索[可输入特殊字符,也可以是组合键("Shift+Home"、"Alt+Enter")]
|
|
|
await searchBoxLocator.PressAsync("Enter");
|
|
|
|
|
|
await page.WaitForLoadStateAsync();
|
|
|
|
|
|
//截图
|
|
|
await page.ScreenshotAsync(new()
|
|
|
{
|
|
|
Path = "Bing.Firefox.Screenshot.png"
|
|
|
});
|
|
|
|
|
|
//网页保存为Pdf文件
|
|
|
//await page.PdfAsync(new()
|
|
|
//{
|
|
|
// Path = "Bing.Firefox.pdf",
|
|
|
// DisplayHeaderFooter = false,
|
|
|
// Format = "A4"
|
|
|
//});
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region WebKit
|
|
|
[Fact]
|
|
|
public async void Baidu_WebKit_Test()
|
|
|
{
|
|
|
using var playwright = await Playwright.CreateAsync();
|
|
|
|
|
|
//浏览器:指定 chrome
|
|
|
await using var browser = await playwright.Webkit.LaunchAsync(new BrowserTypeLaunchOptions()
|
|
|
{
|
|
|
SlowMo = 50, //慢速
|
|
|
Headless = false, // 关闭无头模式(有界面
|
|
|
Devtools = false, // 启用开发者工具
|
|
|
ChromiumSandbox = true, // 关闭浏览器沙盒
|
|
|
ExecutablePath = string.Empty, // 不指定浏览器可执行文件位置,会自动寻找 ms-playwright 下载的浏览器
|
|
|
DownloadsPath = "download",
|
|
|
});
|
|
|
|
|
|
//页面
|
|
|
var page = await browser.NewPageAsync();
|
|
|
|
|
|
//页面响应
|
|
|
var response = await page.GotoAsync("https://www.baidu.com/");
|
|
|
|
|
|
//定位器:搜索框
|
|
|
var searchBoxLocator = page.GetByRole(AriaRole.Textbox).Nth(0);
|
|
|
|
|
|
//元素个数
|
|
|
var count = await searchBoxLocator.CountAsync();
|
|
|
|
|
|
//xUnit断言
|
|
|
Assert.True(count > 0);
|
|
|
|
|
|
//Playwright断言
|
|
|
await Microsoft.Playwright.Assertions.Expect(searchBoxLocator).ToHaveCountAsync(1);
|
|
|
|
|
|
//输入搜索内容前部分(一次性全部输入)
|
|
|
//await searchBoxLocator.FillAsync("Playwright");
|
|
|
|
|
|
//输入搜索内容后部分(模拟用户输入:每个字符之间有延时)
|
|
|
await searchBoxLocator.PressSequentiallyAsync("Playwright.NET", new LocatorPressSequentiallyOptions { Delay = 200 });
|
|
|
|
|
|
//输入回车:确认搜索[可输入特殊字符,也可以是组合键("Shift+Home"、"Alt+Enter")]
|
|
|
await searchBoxLocator.PressAsync("Enter");
|
|
|
|
|
|
//等待
|
|
|
await page.WaitForLoadStateAsync(LoadState.DOMContentLoaded);
|
|
|
|
|
|
//截图
|
|
|
await page.ScreenshotAsync(new()
|
|
|
{
|
|
|
Path = "Baidu.WebKit.Screenshot.png"
|
|
|
});
|
|
|
|
|
|
//网页保存为Pdf文件:FireFox不支持
|
|
|
//await page.PdfAsync(new()
|
|
|
//{
|
|
|
// Path = "Baidu.WebKit.pdf",
|
|
|
// DisplayHeaderFooter = false,
|
|
|
// Format = "A4"
|
|
|
//});
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region WebAPI
|
|
|
/// <summary>
|
|
|
/// 使用免费接口
|
|
|
/// </summary>
|
|
|
[Fact]
|
|
|
public async Task WebAPI_TestAsync()
|
|
|
{
|
|
|
//https://docs.tenapi.cn/ 免费接口
|
|
|
//IP查询 https://tenapi.cn/v2/getip?ip=192.168.1.1
|
|
|
|
|
|
using var playwright = await Playwright.CreateAsync();
|
|
|
var apiRequestContext = await playwright.APIRequest.NewContextAsync(new APIRequestNewContextOptions()
|
|
|
{
|
|
|
BaseURL="https://tenapi.cn",
|
|
|
ExtraHTTPHeaders = new Dictionary<string, string>()
|
|
|
{
|
|
|
{ "Accept","text/html"},
|
|
|
|
|
|
//全局认证
|
|
|
{ "Authorization","Bear a.b.c"}
|
|
|
},
|
|
|
//HttpCredentials = new HttpCredentials() { Origin="http://localhost:8060",Username="admin",Password="123456" },
|
|
|
//IgnoreHTTPSErrors = true, //设置代理时,忽略证书错误
|
|
|
Timeout = 30*1000,
|
|
|
});
|
|
|
|
|
|
var apiResponse = await apiRequestContext.GetAsync("v2/getip?ip=192.168.1.1");
|
|
|
|
|
|
Assert.True(apiResponse.Ok);
|
|
|
|
|
|
var ipResult = await apiResponse.JsonAsync<TenApiReturnBase<GetIP>>();
|
|
|
|
|
|
Assert.NotNull(ipResult);
|
|
|
Assert.IsType<TenApiReturnBase<GetIP>>(ipResult);
|
|
|
|
|
|
Assert.Equal("获取成功", ipResult.msg);
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 使用Fiddler抓包:设置Fiddler为代理服务器,必须先启动Fiddler
|
|
|
/// </summary>
|
|
|
[Fact]
|
|
|
public async Task WebAPI_FiddleProxy_TestAsync()
|
|
|
{
|
|
|
//https://docs.tenapi.cn/ 免费接口
|
|
|
//IP查询 https://tenapi.cn/v2/getip?ip=192.168.1.1
|
|
|
|
|
|
using var playwright = await Playwright.CreateAsync();
|
|
|
var apiRequestContext = await playwright.APIRequest.NewContextAsync(new APIRequestNewContextOptions()
|
|
|
{
|
|
|
BaseURL = "https://tenapi.cn",
|
|
|
ExtraHTTPHeaders = new Dictionary<string, string>()
|
|
|
{
|
|
|
{ "Accept","text/html"},
|
|
|
{ "Authorization","Bear a.b.c"}
|
|
|
},
|
|
|
IgnoreHTTPSErrors = true, //设置代理时,忽略证书错误
|
|
|
Timeout = 30 * 1000,
|
|
|
Proxy = new Proxy() { Server = "http://127.0.0.1:8888" }
|
|
|
});
|
|
|
|
|
|
var apiResponse = await apiRequestContext.GetAsync("v2/getip?ip=192.168.1.1");
|
|
|
|
|
|
Assert.True(apiResponse.Ok);
|
|
|
|
|
|
var ipResult = await apiResponse.JsonAsync<TenApiReturnBase<GetIP>>();
|
|
|
|
|
|
Assert.NotNull(ipResult);
|
|
|
Assert.IsType<TenApiReturnBase<GetIP>>(ipResult);
|
|
|
|
|
|
Assert.Equal("获取成功", ipResult.msg);
|
|
|
|
|
|
}
|
|
|
#endregion
|
|
|
}
|
|
|
} |