You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Selenium+Specflow单点登录测试:页面跳转后LocalStorage丢失求助

Selenium+Specflow单点登录测试:LocalStorage Token跳转丢失问题

问题描述

我正在用Selenium和Specflow开发冒烟测试的单点登录方案,目前已能从响应中提取Access Token并存入FeatureContext,后续测试时重新写入LocalStorage以跳过登录。但遇到一个问题:页面跳转后LocalStorage会被清空,导致跳转新页面时回到登录页。我不想用每次点击都重设LocalStorage的笨方法,求更优雅的解决方案。

注:测试的网站仅使用token,不依赖cookie,cookie相关方案不适用。

获取Token的代码

string loginToken = ExtractAuthTokenFromResponseBody();
featureContext["auth"] = loginToken;

当前设置LocalStorage的代码

我觉得其中设置请求头的操作可能不正确,但移除后无法正常运行,原因未知:

// 导航到页面
loginPage.Navigate(testConfiguration.URL);

// 设置LocalStorage
string nameOfLocalStorage = "Hard coded for know until work more cleanly";
string newTokenValue = featureContext["auth"].ToString();
string script = "var newTokenValue = '" + newTokenValue + "';" + "localStorage.setItem('" + nameOfLocalStorage + "', newTokenValue);";
((IJavaScriptExecutor)webDriver).ExecuteScript(script);

// 添加请求头的操作
var client = new HttpClient();
JObject json = JObject.Parse(newTokenValue);
string idToken = (string)json["id_token"];
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", idToken);
HttpResponseMessage response = await client.GetAsync(testConfiguration.URL);
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
webDriver.Navigate().GoToUrl(testConfiguration.Url);

当前现象:调用GoToUrl能正常进入主页,但点击跳转新页面时LocalStorage为空,被迫回到登录页。


解决方案

1. 修正LocalStorage键名

你当前硬编码的nameOfLocalStorage大概率和前端实际读取的键名不匹配,导致前端无法识别token,进而触发重新登录。先排查前端代码(或通过浏览器开发者工具查看),找到实际存储token的键名,替换硬编码值。

2. 移除冗余的HttpClient请求

你用HttpClient发起的请求是独立于Selenium浏览器会话的,这部分操作对浏览器的LocalStorage和会话状态没有任何帮助,反而可能造成状态不一致。移除这部分代码,调整LocalStorage设置逻辑:

// 导航到目标页面
loginPage.Navigate(testConfiguration.URL);

// 等待页面完全加载
WebDriverWait wait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(10));
wait.Until(d => ((IJavaScriptExecutor)d).ExecuteScript("return document.readyState").ToString() == "complete");

// 设置LocalStorage(替换为实际键名)
string tokenKey = "auth_token"; // 示例键名,替换为实际值
string newTokenValue = featureContext["auth"].ToString();
string script = $"localStorage.setItem('{tokenKey}', '{newTokenValue}');";
((IJavaScriptExecutor)webDriver).ExecuteScript(script);

// 刷新页面,让前端读取LocalStorage中的token
webDriver.Navigate().Refresh();

3. 使用DevTools API持久化LocalStorage(推荐)

对于Chrome/Edge等现代浏览器,利用Selenium的DevTools API直接操作浏览器存储,比JavaScript执行更可靠,且能确保同域名下页面跳转时LocalStorage不丢失:

// 初始化DevTools会话
var devTools = webDriver as IDevTools;
var session = devTools.CreateDevToolsSession();

// 启用Storage模块
await session.SendCommandAsync(new StorageEnableCommandSettings());

// 设置LocalStorage项
await session.SendCommandAsync(new StorageSetLocalStorageItemCommandSettings
{
    Key = "实际的token键名",
    Value = featureContext["auth"].ToString(),
    Origin = testConfiguration.URL // 目标页面的域名,确保同源
});

// 导航到页面,此时LocalStorage已提前配置完成
webDriver.Navigate().GoToUrl(testConfiguration.URL);

4. 检查页面跳转的同源性

如果跳转的页面属于不同域名,浏览器同源策略会阻止LocalStorage共享。这种情况下:

  • 确认所有测试页面是否属于同一主域名,若跨域则需前端配置token跨域共享(不属于测试代码调整范围)
  • 若必须跨域测试,可针对每个域名单独执行一次LocalStorage设置逻辑(但比点击重设更高效,可封装成公共方法)

内容的提问来源于stack exchange,提问作者oisin1min

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 06:05:31