Files
story/test/e2e/visual-ops-sensitive-access-request.mjs
T

280 lines
26 KiB
JavaScript
Raw Normal View History

2026-08-26 06:41:07 +08:00
import { createRequire } from "node:module";
import { randomUUID } from "node:crypto";
import { execFileSync } from "node:child_process";
import { mkdir } from "node:fs/promises";
import { fileURLToPath } from "node:url";
const require = createRequire(process.env.PLAYWRIGHT_REQUIRE_FROM ?? import.meta.url);
const { chromium } = require("playwright");
const outputDirectory = new URL("./screenshots/", import.meta.url);
const webURL = process.env.VISUAL_WEB_URL ?? "http://localhost:3100";
const webHostPattern = new RegExp(new URL(webURL).host.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
const oidcURLPattern = new RegExp(process.env.VISUAL_OIDC_URL_PATTERN ?? "localhost:58180");
const username = process.env.VISUAL_USERNAME ?? "owner";
const password = process.env.VISUAL_PASSWORD ?? "LocalOnly123!";
const contextID = randomUUID();
const contextPublicID = randomUUID();
const conversationID = randomUUID();
const conversationPublicID = randomUUID();
const jobID = randomUUID();
const jobPublicID = randomUUID();
const jobAggregateID = randomUUID();
const issueOpenID = randomUUID();
const issueOpenPublicID = randomUUID();
const issueProgressID = randomUUID();
const issueProgressPublicID = randomUUID();
const issueResolvedID = randomUUID();
const issueResolvedPublicID = randomUUID();
const issueVerifiedID = randomUUID();
const issueVerifiedPublicID = randomUUID();
const issueClosedID = randomUUID();
const issueClosedPublicID = randomUUID();
const accessReviewID = randomUUID();
const accessReviewPublicID = randomUUID();
await mkdir(outputDirectory, { recursive: true });
function psql(statement) {
return execFileSync("docker", ["compose", "exec", "-T", "postgres", "psql", "-v", "ON_ERROR_STOP=1", "-U", "voice", "-d", "voice_platform", "-Atc", statement], {
cwd: process.cwd(), encoding: "utf8", stdio: ["ignore", "pipe", "pipe"]
}).trim();
}
function cleanup() {
psql(`BEGIN;
DELETE FROM integration_issue WHERE id IN ('${issueOpenID}'::uuid,'${issueProgressID}'::uuid,'${issueResolvedID}'::uuid,'${issueVerifiedID}'::uuid,'${issueClosedID}'::uuid);
DELETE FROM outbox_event WHERE id='${jobID}'::uuid;
DELETE FROM ops_sensitive_access_request WHERE conversation_id='${conversationID}'::uuid;
DELETE FROM conversation_state_history WHERE conversation_id='${conversationID}'::uuid;
DELETE FROM conversation WHERE id='${conversationID}'::uuid;
DELETE FROM context_snapshot WHERE id='${contextID}'::uuid;
COMMIT;`);
}
psql(`BEGIN;
INSERT INTO context_snapshot(id,public_id,tenant_id,subject_id,profile_version,consent_snapshot_id,memory_versions,prompt_bundle_version,engine_mode,content_digest,sanitized_summary,preparation_status)
VALUES('${contextID}'::uuid,'${contextPublicID}'::uuid,'10000000-0000-0000-0000-000000000001'::uuid,'10000000-0000-0000-0000-000000000401'::uuid,1,'10000000-0000-0000-0000-000000000701'::uuid,'[]'::jsonb,'visual-sensitive-request-v1','s2s_hybrid','1111111111111111111111111111111111111111111111111111111111111111','运营敏感访问申请页面夹具','READY');
INSERT INTO conversation(id,public_id,tenant_id,household_id,subject_id,device_id,consent_snapshot_id,context_snapshot_id,provider_task_ref,engine_mode,retention_mode,status,allocation_expires_at,started_at,ended_at,stop_reason)
VALUES('${conversationID}'::uuid,'${conversationPublicID}'::uuid,'10000000-0000-0000-0000-000000000001'::uuid,'10000000-0000-0000-0000-000000000201'::uuid,'10000000-0000-0000-0000-000000000401'::uuid,'10000000-0000-0000-0000-000000000501'::uuid,'10000000-0000-0000-0000-000000000701'::uuid,'${contextID}'::uuid,'visual-sensitive-${conversationPublicID}','s2s_hybrid','transcript_only','ROOM_ISSUED',now()+interval '5 minutes',now()-interval '2 minutes',NULL,NULL);
INSERT INTO conversation_state_history(conversation_id,from_status,to_status,reason,source,occurred_at)
VALUES('${conversationID}'::uuid,NULL,'ROOM_ISSUED','visual fixture','platform',now()-interval '2 minutes');
INSERT INTO outbox_event(id,public_id,tenant_id,aggregate_type,aggregate_id,event_type,payload,status,attempt_count,last_error_code,dead_at,payload_hash)
VALUES('${jobID}'::uuid,'${jobPublicID}'::uuid,'10000000-0000-0000-0000-000000000001'::uuid,'visual_control','${jobAggregateID}'::uuid,'platform.noop','{}'::jsonb,'dead',8,'VISUAL_DEPENDENCY_FAILURE',now(),repeat('0',64));
INSERT INTO integration_issue(id,public_id,tenant_id,phenomenon,severity,device_id,conversation_id,occurred_at,request_id,responsible_party,status,resolution_result,root_cause,fixed_version,regression_conclusion,regression_evidence,created_by,updated_by,version)
VALUES
('${issueOpenID}'::uuid,'${issueOpenPublicID}'::uuid,'10000000-0000-0000-0000-000000000001'::uuid,'页面流转夹具:待处理问题','MEDIUM','10000000-0000-0000-0000-000000000501'::uuid,'${conversationID}'::uuid,now()-interval '5 minutes','visual-issue-open','硬件团队','OPEN',NULL,NULL,NULL,NULL,NULL,'10000000-0000-0000-0000-000000000101'::uuid,'10000000-0000-0000-0000-000000000101'::uuid,3),
('${issueProgressID}'::uuid,'${issueProgressPublicID}'::uuid,'10000000-0000-0000-0000-000000000001'::uuid,'页面流转夹具:处理中问题','MEDIUM','10000000-0000-0000-0000-000000000501'::uuid,'${conversationID}'::uuid,now()-interval '4 minutes','visual-issue-progress','Agent研发组','IN_PROGRESS',NULL,NULL,NULL,NULL,NULL,'10000000-0000-0000-0000-000000000101'::uuid,'10000000-0000-0000-0000-000000000101'::uuid,4),
('${issueResolvedID}'::uuid,'${issueResolvedPublicID}'::uuid,'10000000-0000-0000-0000-000000000001'::uuid,'页面流转夹具:待回归问题','LOW','10000000-0000-0000-0000-000000000501'::uuid,'${conversationID}'::uuid,now()-interval '3 minutes','visual-issue-resolved','云端研发组','RESOLVED','已修复状态映射','状态映射遗漏','0.56.0-rc.1',NULL,NULL,'10000000-0000-0000-0000-000000000101'::uuid,'10000000-0000-0000-0000-000000000101'::uuid,5),
('${issueVerifiedID}'::uuid,'${issueVerifiedPublicID}'::uuid,'10000000-0000-0000-0000-000000000001'::uuid,'页面流转夹具:已验证问题','LOW','10000000-0000-0000-0000-000000000501'::uuid,'${conversationID}'::uuid,now()-interval '2 minutes','visual-issue-verified','云端研发组','VERIFIED','已修复状态映射','状态映射遗漏','0.56.0-rc.1','连续验证3次均未复现','请求 visual-regression-001','10000000-0000-0000-0000-000000000101'::uuid,'10000000-0000-0000-0000-000000000101'::uuid,6),
('${issueClosedID}'::uuid,'${issueClosedPublicID}'::uuid,'10000000-0000-0000-0000-000000000001'::uuid,'页面流转夹具:已关闭问题','LOW','10000000-0000-0000-0000-000000000501'::uuid,'${conversationID}'::uuid,now()-interval '1 minute','visual-issue-closed','云端研发组','CLOSED','已修复状态映射','状态映射遗漏','0.56.0-rc.1','连续验证3次均未复现','请求 visual-regression-002','10000000-0000-0000-0000-000000000101'::uuid,'10000000-0000-0000-0000-000000000101'::uuid,7);
INSERT INTO ops_sensitive_access_request(id,public_id,tenant_id,conversation_id,requester_user_id,capabilities,reason,requested_expires_at,status,version)
VALUES('${accessReviewID}'::uuid,'${accessReviewPublicID}'::uuid,'10000000-0000-0000-0000-000000000001'::uuid,'${conversationID}'::uuid,'10000000-0000-0000-0000-000000000102'::uuid,ARRAY['RECORDING_PLAY','TRANSCRIPT_READ'],'页面审批夹具:核对转写时间轴和原录音片段',now()+interval '1 hour','PENDING',4);
COMMIT;`);
const browser = await chromium.launch({ headless: true, executablePath: process.env.CHROME_PATH ?? "C:/Program Files/Google/Chrome/Application/chrome.exe" });
const page = await browser.newPage({ viewport: { width: 1440, height: 1100 }, deviceScaleFactor: 1 });
const consoleErrors = [];
const failedRequests = [];
const accessMutations = [];
const controlMutations = [];
const issueMutations = [];
page.on("console", (message) => { if (message.type() === "error") consoleErrors.push(message.text()); });
page.on("request", (request) => {
if (request.method() === "POST" && /\/api\/v1\/ops\/sensitive-access-requests(\/|$)/.test(request.url())) accessMutations.push(`${request.method()} ${request.url()}`);
if (request.method() === "POST" && /\/api\/v1\/ops\/diagnostics\/(conversations|devices|jobs|bundles)(\/|$)/.test(request.url())) controlMutations.push(`${request.method()} ${request.url()}`);
if (request.method() === "PATCH" && /\/api\/v1\/ops\/integration-issues\//.test(request.url())) issueMutations.push(`${request.method()} ${request.url()}`);
});
page.on("requestfailed", (request) => {
const failure = request.failure()?.errorText ?? "failed";
const requestURL = new URL(request.url());
if (request.method() === "GET" && requestURL.pathname === "/api/v1/events" && failure.includes("ERR_ABORTED")) return;
failedRequests.push(`${request.method()} ${request.url()} ${failure}`);
});
try {
await page.goto(`${webURL}/?workspace=diagnostics`, { waitUntil: "networkidle" });
await page.getByRole("button", { name: "登录研发环境" }).click();
await page.waitForURL(oidcURLPattern);
await page.locator("#username").fill(username);
await page.locator("#password").fill(password);
await page.locator("#kc-login").click();
await page.waitForURL(webHostPattern, { timeout: 15000 });
await page.getByRole("heading", { name: "设备与通话联调" }).waitFor();
await page.getByLabel("检索字段").selectOption("conversation_id");
await page.getByLabel("精确编号").fill(conversationPublicID);
await page.getByRole("button", { name: "查询", exact: true }).click();
const resultCard = page.locator(".diagnostic-card").filter({ hasText: conversationPublicID }).first();
await resultCard.waitFor();
await page.getByRole("button", { name: "导出脱敏诊断包" }).click();
const bundleForm = page.getByRole("form", { name: "脱敏诊断包导出" });
await bundleForm.waitFor();
const bundleTargetBound = (await bundleForm.textContent())?.includes(conversationPublicID) === true && (await bundleForm.textContent())?.includes("通话编号") === true;
const bundleEmptyReasonDisabled = await bundleForm.getByRole("button", { name: "生成并下载" }).isDisabled();
await bundleForm.getByLabel("导出原因").fill("用于验证当前联调记录的脱敏字段和状态关联");
const bundleCompletedEnabled = await bundleForm.getByRole("button", { name: "生成并下载" }).isEnabled();
await bundleForm.getByRole("button", { name: "取消" }).click();
const bundleCancelClosedForm = await bundleForm.count() === 0;
const controlForm = page.getByRole("form", { name: "受控联调操作" });
await resultCard.getByRole("button", { name: "刷新配置" }).click();
await controlForm.waitFor();
const refreshEmptyReasonDisabled = await controlForm.getByRole("button", { name: "刷新设备配置" }).isDisabled();
const refreshTargetBound = (await controlForm.textContent())?.includes("10000000-0000-0000-0000-000000000511") === true;
await controlForm.getByLabel("操作原因").fill("设备已在线,核对配置版本后重新触发拉取");
const refreshCompletedEnabled = await controlForm.getByRole("button", { name: "刷新设备配置" }).isEnabled();
await controlForm.getByRole("button", { name: "取消" }).click();
await resultCard.getByRole("button", { name: "状态对账" }).click();
await controlForm.waitFor();
const reconcileTargetBound = (await controlForm.textContent())?.includes(conversationPublicID) === true;
await controlForm.getByLabel("操作原因").fill("云端与供应商任务状态需要重新核对");
const reconcileCompletedEnabled = await controlForm.getByRole("button", { name: "执行状态对账" }).isEnabled();
await controlForm.getByRole("button", { name: "取消" }).click();
await resultCard.getByRole("button", { name: "安全停止" }).click();
await controlForm.waitFor();
await controlForm.getByLabel("操作原因").fill("联调异常已复现,停止当前夹具通话");
const stopBlockedBeforeAcknowledgement = await controlForm.getByRole("button", { name: "安全停止通话" }).isDisabled();
await controlForm.getByLabel("我确认停止操作只针对上方指定通话,并已核对当前状态").check();
const stopEnabledAfterAcknowledgement = await controlForm.getByRole("button", { name: "安全停止通话" }).isEnabled();
await controlForm.getByRole("button", { name: "取消" }).click();
await resultCard.getByRole("button", { name: "吊销设备" }).click();
await controlForm.waitFor();
await controlForm.getByLabel("操作原因").fill("仅验证吊销确认门禁,不执行实际吊销");
const revokeBlockedBeforeAcknowledgement = await controlForm.getByRole("button", { name: "吊销设备身份" }).isDisabled();
await controlForm.getByLabel("我确认吊销后该设备的后续签名请求会被拒绝").check();
const revokeEnabledAfterAcknowledgement = await controlForm.getByRole("button", { name: "吊销设备身份" }).isEnabled();
await page.screenshot({ path: fileURLToPath(new URL("ops-controlled-diagnostic-action.png", outputDirectory)), fullPage: true });
await controlForm.getByRole("button", { name: "取消" }).click();
const controlCancelClosedForm = await controlForm.count() === 0;
await page.getByRole("button", { name: "刷新任务" }).click();
const jobCard = page.locator(".diagnostic-card").filter({ hasText: "platform.noop" }).filter({ hasText: "visual_control" }).first();
await jobCard.waitFor();
await jobCard.getByRole("button", { name: "受控重试" }).click();
const retryForm = page.getByRole("form", { name: "死信任务受控重试" });
await retryForm.waitFor();
const retryTargetBound = (await retryForm.textContent())?.includes(jobPublicID) === true && (await retryForm.textContent())?.includes("VISUAL_DEPENDENCY_FAILURE") === true;
const retryEmptyReasonDisabled = await retryForm.getByRole("button", { name: "确认受控重试" }).isDisabled();
await retryForm.getByLabel("重试原因").fill("依赖恢复情况已复核,本次仅验证页面门禁,不提交重试");
const retryBlockedBeforeAcknowledgement = await retryForm.getByRole("button", { name: "确认受控重试" }).isDisabled();
await retryForm.getByLabel("我已确认根因或依赖问题已经处理,并理解失败后任务仍可能再次进入死信").check();
const retryEnabledAfterAcknowledgement = await retryForm.getByRole("button", { name: "确认受控重试" }).isEnabled();
await page.screenshot({ path: fileURLToPath(new URL("ops-diagnostic-retry-and-export.png", outputDirectory)), fullPage: true });
await retryForm.getByRole("button", { name: "取消" }).click();
const retryCancelClosedForm = await retryForm.count() === 0;
await page.getByLabel("问题状态筛选").selectOption("");
await page.waitForTimeout(400);
await page.getByRole("button", { name: "刷新清单" }).click();
const openIssueCard = page.locator(".integration-issue-card").filter({ hasText: "页面流转夹具:待处理问题" });
const progressIssueCard = page.locator(".integration-issue-card").filter({ hasText: "页面流转夹具:处理中问题" });
const resolvedIssueCard = page.locator(".integration-issue-card").filter({ hasText: "页面流转夹具:待回归问题" });
const verifiedIssueCard = page.locator(".integration-issue-card").filter({ hasText: "页面流转夹具:已验证问题" });
const closedIssueCard = page.locator(".integration-issue-card").filter({ hasText: "页面流转夹具:已关闭问题" });
await Promise.all([openIssueCard.waitFor(), progressIssueCard.waitFor(), resolvedIssueCard.waitFor(), verifiedIssueCard.waitFor(), closedIssueCard.waitFor()]);
const issueForm = page.getByRole("form", { name: "联调问题流转编辑" });
await openIssueCard.getByRole("button", { name: "调整级别" }).click();
await issueForm.waitFor();
const severityTargetBound = (await issueForm.textContent())?.includes(issueOpenPublicID) === true && (await issueForm.textContent())?.includes("ETag版本 3") === true;
const sameSeverityDisabled = await issueForm.getByRole("button", { name: "保存级别" }).isDisabled();
await issueForm.getByLabel("严重级别").selectOption("CRITICAL");
const changedSeverityEnabled = await issueForm.getByRole("button", { name: "保存级别" }).isEnabled();
await issueForm.getByRole("button", { name: "取消" }).click();
await openIssueCard.getByRole("button", { name: "接手处理" }).click();
await issueForm.getByLabel("接手责任方").fill("");
const takeEmptyPartyDisabled = await issueForm.getByRole("button", { name: "确认接手" }).isDisabled();
await issueForm.getByLabel("接手责任方").fill("联调值班组");
const takeCompletedEnabled = await issueForm.getByRole("button", { name: "确认接手" }).isEnabled();
await issueForm.getByRole("button", { name: "取消" }).click();
await progressIssueCard.getByRole("button", { name: "登记解决" }).click();
const resolveEmptyDisabled = await issueForm.getByRole("button", { name: "提交解决记录" }).isDisabled();
await issueForm.getByLabel("根因结论").fill("设备状态映射缺少一个稳定分支");
await issueForm.getByLabel("修复版本或不可变构建标识").fill("0.56.0-rc.2");
await issueForm.getByLabel("解决结果").fill("补齐映射并完成本地复核");
const resolveCompletedEnabled = await issueForm.getByRole("button", { name: "提交解决记录" }).isEnabled();
await issueForm.getByRole("button", { name: "取消" }).click();
await resolvedIssueCard.getByRole("button", { name: "登记回归" }).click();
const verifyEmptyDisabled = await issueForm.getByRole("button", { name: "提交回归记录" }).isDisabled();
await issueForm.getByLabel("脱敏回归证据").fill("请求 visual-regression-003,连续执行3次");
await issueForm.getByLabel("回归结论").fill("三次结果一致,原问题未再复现");
const verifyCompletedEnabled = await issueForm.getByRole("button", { name: "提交回归记录" }).isEnabled();
await issueForm.getByRole("button", { name: "取消" }).click();
await verifiedIssueCard.getByRole("button", { name: "关闭问题" }).click();
const closeBlockedBeforeAcknowledgement = await issueForm.getByRole("button", { name: "确认关闭" }).isDisabled();
await issueForm.getByLabel("我已复核根因、修复版本、解决结果及回归证据,同意关闭该问题").check();
const closeEnabledAfterAcknowledgement = await issueForm.getByRole("button", { name: "确认关闭" }).isEnabled();
await page.screenshot({ path: fileURLToPath(new URL("ops-integration-issue-workflow.png", outputDirectory)), fullPage: true });
await issueForm.getByRole("button", { name: "取消" }).click();
await closedIssueCard.getByRole("button", { name: "重新打开" }).click();
await issueForm.getByLabel("重新处理责任方").fill("");
const reopenEmptyPartyDisabled = await issueForm.getByRole("button", { name: "重新打开" }).isDisabled();
await issueForm.getByLabel("重新处理责任方").fill("回归复核组");
const reopenCompletedEnabled = await issueForm.getByRole("button", { name: "重新打开" }).isEnabled();
await issueForm.getByRole("button", { name: "取消" }).click();
const issueCancelClosedForm = await issueForm.count() === 0;
await page.getByRole("button", { name: "刷新申请" }).click();
const accessReviewCard = page.locator(".diagnostic-card").filter({ hasText: "页面审批夹具:核对转写时间轴和原录音片段" });
await accessReviewCard.waitFor();
await accessReviewCard.getByRole("button", { name: "批准" }).click();
const reviewForm = page.getByRole("form", { name: "临时敏感访问审批" });
await reviewForm.waitFor();
const approvalText = await reviewForm.textContent();
const approvalTargetBound = approvalText?.includes(accessReviewPublicID) === true && approvalText?.includes("10000000-0000-0000-0000-000000000112") === true && approvalText?.includes("读取最终字幕") === true && approvalText?.includes("播放原录音") === true && approvalText?.includes("版本 4") === true;
const approvalEmptyReasonDisabled = await reviewForm.getByRole("button", { name: "确认批准" }).isDisabled();
await reviewForm.getByLabel("批准依据").fill("已复核单次通话、最小能力、问题范围和一小时有效期");
const approvalBlockedBeforeAcknowledgement = await reviewForm.getByRole("button", { name: "确认批准" }).isDisabled();
await reviewForm.getByLabel("我确认申请人不是本人,已复核单次通话、最小能力和到期时间,批准后只有原申请人可在有效期内使用").check();
const approvalEnabledAfterAcknowledgement = await reviewForm.getByRole("button", { name: "确认批准" }).isEnabled();
await page.screenshot({ path: fileURLToPath(new URL("ops-sensitive-access-review.png", outputDirectory)), fullPage: true });
await reviewForm.getByRole("button", { name: "取消" }).click();
await accessReviewCard.getByRole("button", { name: "拒绝" }).click();
const rejectionTargetBound = (await reviewForm.textContent())?.includes(accessReviewPublicID) === true && (await reviewForm.textContent())?.includes("终止本次申请") === true;
const rejectionEmptyReasonDisabled = await reviewForm.getByRole("button", { name: "确认拒绝" }).isDisabled();
await reviewForm.getByLabel("拒绝原因").fill("申请包含原录音播放,但当前排障说明不足以支持该能力");
const rejectionCompletedEnabled = await reviewForm.getByRole("button", { name: "确认拒绝" }).isEnabled();
await reviewForm.getByRole("button", { name: "取消" }).click();
const reviewCancelClosedForm = await reviewForm.count() === 0;
await resultCard.getByRole("button", { name: "申请临时敏感访问" }).click();
const form = page.getByRole("form", { name: "临时敏感访问申请" });
await form.waitFor();
const submit = form.getByRole("button", { name: "提交审批" });
const emptyReasonDisabled = await submit.isDisabled();
const transcript = form.getByLabel("读取本次通话最终字幕");
const transcriptMandatory = await transcript.isChecked() && await transcript.isDisabled();
const recording = form.getByLabel("同时申请本次通话原录音播放");
const recordingInitiallyOptional = !(await recording.isChecked());
await form.getByLabel("排障理由").fill("核对本次转写时间轴与设备错误码是否一致");
await recording.check();
await form.getByLabel("有效期").selectOption("240");
const completedFormEnabled = await submit.isEnabled();
const fourHourSelected = await form.getByLabel("有效期").inputValue() === "240";
await page.screenshot({ path: fileURLToPath(new URL("ops-sensitive-access-request.png", outputDirectory)), fullPage: true });
await form.getByRole("button", { name: "取消" }).click();
const cancelClosedForm = await form.count() === 0;
const overflow = await page.evaluate(() => [...document.querySelectorAll("body *")]
.filter((element) => element instanceof HTMLElement && element.scrollWidth > element.clientWidth + 2 && getComputedStyle(element).overflowX === "visible")
.slice(0, 20)
.map((element) => `${element.tagName}.${element.className}: ${element.clientWidth}/${element.scrollWidth}`));
const result = { bundleTargetBound, bundleEmptyReasonDisabled, bundleCompletedEnabled, bundleCancelClosedForm, refreshEmptyReasonDisabled, refreshTargetBound, refreshCompletedEnabled, reconcileTargetBound, reconcileCompletedEnabled, stopBlockedBeforeAcknowledgement, stopEnabledAfterAcknowledgement, revokeBlockedBeforeAcknowledgement, revokeEnabledAfterAcknowledgement, controlCancelClosedForm, retryTargetBound, retryEmptyReasonDisabled, retryBlockedBeforeAcknowledgement, retryEnabledAfterAcknowledgement, retryCancelClosedForm, severityTargetBound, sameSeverityDisabled, changedSeverityEnabled, takeEmptyPartyDisabled, takeCompletedEnabled, resolveEmptyDisabled, resolveCompletedEnabled, verifyEmptyDisabled, verifyCompletedEnabled, closeBlockedBeforeAcknowledgement, closeEnabledAfterAcknowledgement, reopenEmptyPartyDisabled, reopenCompletedEnabled, issueCancelClosedForm, approvalTargetBound, approvalEmptyReasonDisabled, approvalBlockedBeforeAcknowledgement, approvalEnabledAfterAcknowledgement, rejectionTargetBound, rejectionEmptyReasonDisabled, rejectionCompletedEnabled, reviewCancelClosedForm, emptyReasonDisabled, transcriptMandatory, recordingInitiallyOptional, completedFormEnabled, fourHourSelected, cancelClosedForm, controlMutations, issueMutations, accessMutations, overflow, consoleErrors, failedRequests };
console.log(JSON.stringify(result, null, 2));
if (!bundleTargetBound || !bundleEmptyReasonDisabled || !bundleCompletedEnabled || !bundleCancelClosedForm || !refreshEmptyReasonDisabled || !refreshTargetBound || !refreshCompletedEnabled || !reconcileTargetBound || !reconcileCompletedEnabled || !stopBlockedBeforeAcknowledgement || !stopEnabledAfterAcknowledgement || !revokeBlockedBeforeAcknowledgement || !revokeEnabledAfterAcknowledgement || !controlCancelClosedForm || !retryTargetBound || !retryEmptyReasonDisabled || !retryBlockedBeforeAcknowledgement || !retryEnabledAfterAcknowledgement || !retryCancelClosedForm || !severityTargetBound || !sameSeverityDisabled || !changedSeverityEnabled || !takeEmptyPartyDisabled || !takeCompletedEnabled || !resolveEmptyDisabled || !resolveCompletedEnabled || !verifyEmptyDisabled || !verifyCompletedEnabled || !closeBlockedBeforeAcknowledgement || !closeEnabledAfterAcknowledgement || !reopenEmptyPartyDisabled || !reopenCompletedEnabled || !issueCancelClosedForm || !approvalTargetBound || !approvalEmptyReasonDisabled || !approvalBlockedBeforeAcknowledgement || !approvalEnabledAfterAcknowledgement || !rejectionTargetBound || !rejectionEmptyReasonDisabled || !rejectionCompletedEnabled || !reviewCancelClosedForm || !emptyReasonDisabled || !transcriptMandatory || !recordingInitiallyOptional || !completedFormEnabled || !fourHourSelected || !cancelClosedForm || controlMutations.length || issueMutations.length || accessMutations.length || overflow.length || consoleErrors.length || failedRequests.length) {
throw new Error("Ops sensitive access request visual smoke failed");
}
} finally {
await browser.close();
cleanup();
}