skopix 2.0.60 → 2.0.62
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/commands/dashboard.js +58 -60
- package/package.json +1 -1
|
@@ -3952,6 +3952,38 @@ async function startStepTester(testerId, url, selector, mode, steps) {
|
|
|
3952
3952
|
const page = await ctx.newPage();
|
|
3953
3953
|
|
|
3954
3954
|
if (mode === 'preview' && steps && steps.length > 0) {
|
|
3955
|
+
// Register expose functions FIRST before addInitScript so they're available on DOMContentLoaded
|
|
3956
|
+
await ctx.exposeFunction('__skopixPreviewRun', async ({ index }) => {
|
|
3957
|
+
const s = steps[index];
|
|
3958
|
+
if (!s) return;
|
|
3959
|
+
await page.evaluate(({ i, status }) => { if(window.__skopixUpdatePreview) window.__skopixUpdatePreview(i, null, status); }, { i: index, status: `Running step ${index+1}/${steps.length}...` }).catch(()=>{});
|
|
3960
|
+
const result = await executeStepTesterAction(page, { selector: s.stableSelector||s.selector, action: s.action, value: s.value||'', assertType: s.assertType });
|
|
3961
|
+
const msg = result.passed ? (index+1 >= steps.length ? `✓ All ${steps.length} steps passed!` : `✓ Step ${index+1} passed`) : `✗ Step ${index+1} failed`;
|
|
3962
|
+
await page.evaluate(({ i, r, msg }) => {
|
|
3963
|
+
if(window.__skopixUpdatePreview) window.__skopixUpdatePreview(i, r, msg);
|
|
3964
|
+
}, { i: index, r: { passed: result.passed, error: result.error||null }, msg }).catch(()=>{});
|
|
3965
|
+
});
|
|
3966
|
+
|
|
3967
|
+
await ctx.exposeFunction('__skopixPreviewRunAll', async ({ fromIndex }) => {
|
|
3968
|
+
for (let i = fromIndex; i < steps.length; i++) {
|
|
3969
|
+
const s = steps[i];
|
|
3970
|
+
await page.evaluate(({ i, total }) => { if(window.__skopixUpdatePreview) window.__skopixUpdatePreview(i, null, `Running step ${i+1}/${total}...`); }, { i, total: steps.length }).catch(()=>{});
|
|
3971
|
+
const result = await executeStepTesterAction(page, { selector: s.stableSelector||s.selector, action: s.action, value: s.value||'', assertType: s.assertType });
|
|
3972
|
+
const msg = result.passed ? (i+1 >= steps.length ? `✓ All ${steps.length} steps passed!` : `Running...`) : `✗ Step ${i+1} failed — fix and retry`;
|
|
3973
|
+
await page.evaluate(({ i, r, msg }) => {
|
|
3974
|
+
if(window.__skopixUpdatePreview) window.__skopixUpdatePreview(i, r, msg);
|
|
3975
|
+
}, { i, r: { passed: result.passed, error: result.error||null }, msg }).catch(()=>{});
|
|
3976
|
+
if (!result.passed) break;
|
|
3977
|
+
await new Promise(r => setTimeout(r, 400));
|
|
3978
|
+
}
|
|
3979
|
+
});
|
|
3980
|
+
|
|
3981
|
+
await ctx.exposeFunction('__skopixStopPreview', async () => {
|
|
3982
|
+
try { await browser.close(); } catch {}
|
|
3983
|
+
stepTesterSessions.delete(testerId);
|
|
3984
|
+
});
|
|
3985
|
+
|
|
3986
|
+
// THEN inject toolbar via addInitScript
|
|
3955
3987
|
// PREVIEW MODE — inject steps list toolbar
|
|
3956
3988
|
await ctx.addInitScript((stepsData) => {
|
|
3957
3989
|
window.__skopixPreviewSteps = stepsData;
|
|
@@ -4059,37 +4091,38 @@ async function startStepTester(testerId, url, selector, mode, steps) {
|
|
|
4059
4091
|
});
|
|
4060
4092
|
}, steps.map(s => ({ action: s.action, selector: s.stableSelector||s.selector||'', description: s.description||s.action, value: s.value||'' })));
|
|
4061
4093
|
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
await page.evaluate((
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
if
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4094
|
+
} else {
|
|
4095
|
+
// STEP TESTER MODE — register expose functions FIRST
|
|
4096
|
+
await ctx.exposeFunction('__skopixTesterRun', async ({ sel, action, value }) => {
|
|
4097
|
+
const result = await executeStepTesterAction(page, { selector: sel, action, value });
|
|
4098
|
+
await page.evaluate(({ passed }) => {
|
|
4099
|
+
const el = document.getElementById('__skopix_result');
|
|
4100
|
+
if (el) { el.textContent = passed ? '✓' : '✗'; el.style.color = passed ? '#34d399' : '#ef4444'; }
|
|
4101
|
+
}, { passed: result.passed }).catch(async () => {
|
|
4102
|
+
await new Promise(r => setTimeout(r, 500));
|
|
4103
|
+
await page.evaluate(({ passed }) => {
|
|
4104
|
+
const el = document.getElementById('__skopix_result');
|
|
4105
|
+
if (el) { el.textContent = passed ? '✓' : '✗'; el.style.color = passed ? '#34d399' : '#ef4444'; }
|
|
4106
|
+
}, { passed: result.passed }).catch(() => {});
|
|
4107
|
+
});
|
|
4108
|
+
await page.evaluate(({ passed, sel }) => {
|
|
4109
|
+
try {
|
|
4110
|
+
const target = document.querySelector(sel);
|
|
4111
|
+
if (target) {
|
|
4112
|
+
const orig = target.style.outline;
|
|
4113
|
+
target.style.outline = passed ? '3px solid #34d399' : '3px solid #ef4444';
|
|
4114
|
+
setTimeout(() => { target.style.outline = orig; }, 1500);
|
|
4115
|
+
}
|
|
4116
|
+
} catch {}
|
|
4117
|
+
}, { passed: result.passed, sel }).catch(() => {});
|
|
4084
4118
|
});
|
|
4085
4119
|
|
|
4086
|
-
await ctx.exposeFunction('
|
|
4120
|
+
await ctx.exposeFunction('__skopixTesterStop', async () => {
|
|
4087
4121
|
try { await browser.close(); } catch {}
|
|
4088
4122
|
stepTesterSessions.delete(testerId);
|
|
4089
4123
|
});
|
|
4090
4124
|
|
|
4091
|
-
|
|
4092
|
-
// STEP TESTER MODE — single step toolbar
|
|
4125
|
+
// THEN inject toolbar
|
|
4093
4126
|
await ctx.addInitScript((sel) => {
|
|
4094
4127
|
window.__skopixTesterSelector = sel;
|
|
4095
4128
|
document.addEventListener('DOMContentLoaded', () => {
|
|
@@ -4146,41 +4179,6 @@ async function startStepTester(testerId, url, selector, mode, steps) {
|
|
|
4146
4179
|
});
|
|
4147
4180
|
});
|
|
4148
4181
|
}, selector || '');
|
|
4149
|
-
|
|
4150
|
-
await ctx.exposeFunction('__skopixTesterRun', async ({ sel, action, value }) => {
|
|
4151
|
-
const result = await executeStepTesterAction(page, { selector: sel, action, value });
|
|
4152
|
-
// Update toolbar via exposeFunction callback — more reliable than evaluate
|
|
4153
|
-
await page.evaluate((passed, errMsg) => {
|
|
4154
|
-
const el = document.getElementById('__skopix_result');
|
|
4155
|
-
if (el) {
|
|
4156
|
-
el.textContent = passed ? '✓' : '✗';
|
|
4157
|
-
el.style.color = passed ? '#34d399' : '#ef4444';
|
|
4158
|
-
}
|
|
4159
|
-
}, result.passed, result.error || '').catch(async () => {
|
|
4160
|
-
// If evaluate fails (e.g. page navigated), wait and retry once
|
|
4161
|
-
await new Promise(r => setTimeout(r, 500));
|
|
4162
|
-
await page.evaluate((passed) => {
|
|
4163
|
-
const el = document.getElementById('__skopix_result');
|
|
4164
|
-
if (el) { el.textContent = passed ? '✓' : '✗'; el.style.color = passed ? '#34d399' : '#ef4444'; }
|
|
4165
|
-
}, result.passed).catch(() => {});
|
|
4166
|
-
});
|
|
4167
|
-
// Highlight element
|
|
4168
|
-
await page.evaluate((passed, sel) => {
|
|
4169
|
-
try {
|
|
4170
|
-
const target = document.querySelector(sel);
|
|
4171
|
-
if (target) {
|
|
4172
|
-
const orig = target.style.outline;
|
|
4173
|
-
target.style.outline = passed ? '3px solid #34d399' : '3px solid #ef4444';
|
|
4174
|
-
setTimeout(() => { target.style.outline = orig; }, 1500);
|
|
4175
|
-
}
|
|
4176
|
-
} catch {}
|
|
4177
|
-
}, result.passed, sel).catch(() => {});
|
|
4178
|
-
});
|
|
4179
|
-
|
|
4180
|
-
await ctx.exposeFunction('__skopixTesterStop', async () => {
|
|
4181
|
-
try { await browser.close(); } catch {}
|
|
4182
|
-
stepTesterSessions.delete(testerId);
|
|
4183
|
-
});
|
|
4184
4182
|
}
|
|
4185
4183
|
|
|
4186
4184
|
if (url) await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30000 }).catch(() => {});
|
package/package.json
CHANGED