feedback7 R22-E2EFIX: loadout-battle / teammate-loadout e2e choose 野鬃's S1 + 不装备 in the row's quick choices and expect the default 练度 on the detail card; golden: unchanged

The 0.2.2 干员调配 is one list: a row carries the skills and the elite's modules, and the detail (now opening with
潜能与练度 and 特质) has its module cards below the fold at 1920 × 1080, where the Client's real-mouse click (no
scrolling) found nothing clickable for `.lo-detail .lo-mod[data-module="none"]`. Both suites now tap the row's
`.lo-q--skill[data-skill="0"]` / `.lo-q--mod[data-module="none"]` and wait for the row (aria-pressed) and the detail
(is-on) to agree before the sync; what they assert is unchanged (m.private.loadout → b.start spec → the local sim
runs S1 without the module; the host's card of the guest's unit reads S1 已调配 / 未装备模组).
loadout-battle's detail card check then met 0.2.2's other change: the card's base ATK carries the player's 练度 — the
default 精英2 Lv.60, ×1.1 (576 for the record's 524, effects.json aceffect_char_4); the unit's def keeps 524.

- Tests (SP_E2E=1): loadout-battle 2/2, teammate-loadout 1/1.
This commit is contained in:
sganggs committed 2026-10-08 23:44:02 +08:00
1 parent b972c1fc9e
commit 267a826b58
2 files changed
+19 -7

No files matched your search

+12 -5
View File
@@ -53,9 +53,13 @@ describe('user playtest #2 item 1 — loadout chosen in the UI fights in the loc
await c.page.keyboard.type('野鬃');
await c.page.waitForFunction(() => document.querySelectorAll('.lo-card').length === 1, { timeout: 5000 });
await c.click('.lo-card__pick');
await c.click('.lo-detail .lo-skill[data-skill="0"]');
await c.click('.lo-detail .lo-mod[data-module="none"]');
await c.page.waitForFunction(() => document.querySelector('.lo-skill.is-on[data-skill="0"]') && document.querySelector('.lo-mod.is-on[data-module="none"]'), { timeout: 3000 });
// the row's quick choices (0.2.2: the roster is one list, a row per operator with its skills and the elite's
// modules; the detail's own module cards sit below the fold) — the row and the detail agree on S1 + 不装备
await c.click('.lo-card .lo-q--skill[data-skill="0"]');
await c.click('.lo-card .lo-q--mod[data-module="none"]');
await c.page.waitForFunction(() => document.querySelector('.lo-card .lo-q--skill[data-skill="0"]')?.getAttribute('aria-pressed') === 'true'
&& document.querySelector('.lo-card .lo-q--mod[data-module="none"]')?.getAttribute('aria-pressed') === 'true'
&& document.querySelector('.lo-detail .lo-skill.is-on[data-skill="0"]') && document.querySelector('.lo-detail .lo-mod.is-on[data-module="none"]'), { timeout: 3000 });
await c.page.waitForFunction(() => /已同步/.test(document.querySelector('.lo-sync')?.textContent || ''), { timeout: 8000 });
await c.shot('overlay');
await c.page.keyboard.press('Escape');
@@ -116,8 +120,11 @@ describe('user playtest #2 item 1 — loadout chosen in the UI fights in the loc
assert.ok(detail, 'the detail card opens for the placed elite');
assert.ok(detail.skill.includes(s1.name) && detail.tag, `detail card: ${s1.name} 已调配 (${JSON.stringify(detail)})`);
assert.ok(detail.none && detail.module.includes('未装备模组'), `detail card: 未装备模组 (${JSON.stringify(detail)})`);
// …and the stats / 特性 the unit fights with: no module (ATK 524, interval 1.00 s, "获得1点") — not the default module's
assert.equal(detail.stats['攻击'], String(rec.statsBase.atk), `detail card ATK without the module (${JSON.stringify(detail.stats)})`);
// …and the stats / 特性 the unit fights with: no module (ATK 524, interval 1.00 s, "获得1点") — not the default module's;
// 0.2.2: the card's base value carries the player's 练度, here the default 精英2 Lv.60 (effects.json aceffect_char_4,
// ×1.1 ATK — a multiplier of its own, the unit's def keeps the record's 524)
const t4 = JSON.parse(readFileSync(path.join(ROOT, 'data/effects.json'), 'utf8')).aceffect_char_4.buffs.find((b) => b.key === 'char_attribute_mul').bb;
assert.equal(detail.stats['攻击'], String(Math.round(rec.statsBase.atk * t4.atk)), `detail card ATK without the module, at the default 练度 (${JSON.stringify(detail.stats)})`);
assert.equal(detail.stats['攻击间隔'], '1.00s', 'detail card interval: ASPD 100');
assert.match(detail.trait, /获得1点部署费用/, `detail card 特性 without the module (${detail.trait})`);
await c.shot('detail');
+7 -2
View File
@@ -59,8 +59,13 @@ describe('DESIGN §16 — a teammate\'s unit shows its owner\'s loadout (real se
await guest.page.keyboard.type('野鬃');
await guest.page.waitForFunction(() => document.querySelectorAll('.lo-card').length === 1, { timeout: 5000 });
await guest.click('.lo-card__pick');
await guest.click('.lo-detail .lo-skill[data-skill="0"]');
await guest.click('.lo-detail .lo-mod[data-module="none"]');
// the row's quick choices (0.2.2: the roster is one list, a row per operator with its skills and the elite's
// modules; the detail's own module cards sit below the fold) — the row and the detail agree on S1 + 不装备
await guest.click('.lo-card .lo-q--skill[data-skill="0"]');
await guest.click('.lo-card .lo-q--mod[data-module="none"]');
await guest.page.waitForFunction(() => document.querySelector('.lo-card .lo-q--skill[data-skill="0"]')?.getAttribute('aria-pressed') === 'true'
&& document.querySelector('.lo-card .lo-q--mod[data-module="none"]')?.getAttribute('aria-pressed') === 'true'
&& document.querySelector('.lo-detail .lo-skill.is-on[data-skill="0"]') && document.querySelector('.lo-detail .lo-mod.is-on[data-module="none"]'), { timeout: 3000 });
await guest.page.waitForFunction(() => /已同步/.test(document.querySelector('.lo-sync')?.textContent || ''), { timeout: 8000 });
await guest.page.keyboard.press('Escape');
await guest.page.waitForFunction(() => !document.querySelector('.lo'), { timeout: 3000 });