五个页面按 h5/css 的 style.css → ui-20261009 → ui-20261012 覆盖顺序逐条重排, 换算规则固定为 calc(N * var(--u)) → 2N rpx,固定 px 的字号保持 px。 - app.acss:换回 H5 设计 token(方角小倒角按钮 10rpx、卡片 14rpx、.chev 折线箭头) - splash/profile/history:底图与按钮文字图改用 H5 资源,隐私/政策弹窗按 H5 重排 - report:环形分用 conic-gradient、人脸裁切窗口叠加 face_maps、标记点百分比盒、 侧脸皱纹 pending/unavailable 文案;用 Playwright 抓 H5 94 个选择器几何比对, 整页高 2438.7 vs 2438.67 - camera:淘宝 <camera> 组件在真机整页崩溃(嵌了微信专有的 <cover-view>), 改为默认系统相机 + `config.nativeCamera` 开关 + pages/camtest 冒烟页验证组件 - permissions:淘宝用带前缀的 scope.camera(裸名返回 5022 Scope:camera信息不存在), 先试带前缀再退回裸名,拒绝后不再重复弹窗 - voice:非 HTTPS 资源导致的异常不再冒泡成整页崩溃;app.js 加开发版错误 toast - 开发版入口:权限诊断(启动页/相机页)、相机组件测试 - 测试 20/20(新增权限与相机能力用例)
70 lines
3.6 KiB
JavaScript
70 lines
3.6 KiB
JavaScript
'use strict';
|
|
const { test } = require('node:test'), assert = require('node:assert/strict'), vm = require('node:vm'), fs = require('node:fs'), path = require('node:path');
|
|
function setup(my) {
|
|
const module = { exports: {} };
|
|
vm.runInNewContext(fs.readFileSync(path.join(__dirname, '../utils/permissions.js'), 'utf8'), { module, Promise, Error, my });
|
|
return module.exports;
|
|
}
|
|
// 2026-11-01 真机实测(SDK 2.9.4):淘宝用带前缀的 scope.camera(裸名 camera 返回 5022 "Scope:camera信息不存在")。
|
|
// 所以先试 scope.camera,失败再退到裸名,两者都失败才拒绝,且拒绝后不再重复弹授权。
|
|
test('deny never loops: tries prefixed then bare once, then requires explicit settings', async () => {
|
|
let granted = { 'scope.userInfo': true }, calls = [], openCalls = 0;
|
|
const permissions = setup({
|
|
getSetting({ success }) { success({ authSetting: granted }); },
|
|
authorize({ scopes, success, fail }) { calls.push(scopes); fail({ error: 11, errorMessage: 'no such scope' }); },
|
|
openSetting({ success }) { openCalls++; granted['scope.camera'] = true; success({ authSetting: granted }); }
|
|
});
|
|
await assert.rejects(permissions.ensure('scope.camera'), e => e.permission === 'scope.camera');
|
|
await assert.rejects(permissions.ensure('scope.camera'), e => e.permission === 'scope.camera');
|
|
assert.deepEqual(calls, ['scope.camera', 'camera'], '第二次不再尝试授权');
|
|
assert.equal(openCalls, 0);
|
|
await permissions.open(); await permissions.ensure('scope.camera');
|
|
assert.equal(calls.length, 2, '授权设置里开启后不再调用 authorize');
|
|
assert.equal(openCalls, 1);
|
|
});
|
|
|
|
test('prefixed scope is used first and succeeds without falling back', async () => {
|
|
let calls = [];
|
|
const permissions = setup({
|
|
getSetting({ success }) { success({ authSetting: {} }); },
|
|
authorize({ scopes, success }) { calls.push(scopes); success(); }
|
|
});
|
|
await permissions.ensure('scope.camera');
|
|
assert.deepEqual(calls, ['scope.camera']);
|
|
await permissions.ensure('scope.album');
|
|
assert.deepEqual(calls, ['scope.camera', 'scope.album']);
|
|
});
|
|
|
|
test('existing denial does not reauthorize; short-form settings keys work', async () => {
|
|
let calls = 0;
|
|
const permissions = setup({
|
|
getSetting({ success }) { success({ authSetting: { camera: false, album: true } }); },
|
|
authorize() { calls++; }
|
|
});
|
|
await assert.rejects(permissions.ensure('scope.camera'));
|
|
await permissions.ensure('scope.album');
|
|
assert.equal(calls, 0);
|
|
});
|
|
|
|
test('diagnose reports capability and authorization outcomes', async () => {
|
|
const permissions = setup({
|
|
SDKVersion: '2.9.4',
|
|
canIUse() { return true; },
|
|
getSetting({ success }) { success({ authSetting: { 'scope.camera': true } }); },
|
|
authorize({ scopes, success, fail }) { scopes === 'scope.camera' ? success() : fail({ errorCode: '5022' }); },
|
|
createCameraContext() {}, chooseImage() {}, getImageInfo() {}, createCanvasContext() {}, openSetting() {}
|
|
});
|
|
const info = await permissions.diagnose();
|
|
const text = info.join('\n');
|
|
assert.match(text, /SDKVersion=2\.9\.4/);
|
|
assert.match(text, /createCameraContext: typeof=function canIUse=yes/);
|
|
assert.match(text, /authSetting=\{"scope\.camera":true\}/);
|
|
assert.match(text, /authorize\(scope\.camera\)=ok/);
|
|
});
|
|
|
|
test('cameraSupported requires the native camera API and canIUse', () => {
|
|
assert.equal(setup({ canIUse: () => true }).cameraSupported(), false, '没有 createCameraContext 就不支持');
|
|
assert.equal(setup({ canIUse: () => true, createCameraContext() {} }).cameraSupported(), true);
|
|
assert.equal(setup({ canIUse: (api) => api !== 'camera', createCameraContext() {} }).cameraSupported(), false);
|
|
});
|