You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
37 lines
2.8 KiB
JavaScript
37 lines
2.8 KiB
JavaScript
const assert = require("node:assert/strict");
|
|
const fs = require("node:fs");
|
|
const path = require("node:path");
|
|
|
|
const page = fs.readFileSync(
|
|
path.resolve(__dirname, "../src/views/product/price.vue"),
|
|
"utf8",
|
|
);
|
|
const stepper = page.match(
|
|
/<nav class="step-indicator" aria-label="新产品定价步骤">([\s\S]*?)<\/nav>/,
|
|
)?.[1] || "";
|
|
|
|
assert.ok(stepper, "product pricing must use the shared step-indicator navigation pattern");
|
|
assert.match(stepper, /v-for="step in pricingSteps"/, "the step navigation must be rendered from actual step data");
|
|
assert.match(stepper, /@click="switchStep\(step\.no\)"/, "each pricing step must be navigable");
|
|
assert.match(page, /class="workbench-head workbench-head--actions-only"/, "pricing must use the standard top action row");
|
|
assert.match(page, /@click="exportPriceOutcome"/, "pricing must provide the standard export action");
|
|
assert.ok(page.indexOf("workbench-head--actions-only") < page.indexOf('class="step-indicator"'), "actions must appear before the step indicator");
|
|
assert.ok(page.indexOf('class="step-indicator"') < page.indexOf('<section class="step-card">'), "step content must be inside a separate standard step card");
|
|
assert.match(page, /const pricingSteps = computed\(\(\) => \[/, "the page must define its pricing steps");
|
|
for (const label of ["pricingTitle", "competitorPricingTitle", "valueBasedPricingTitle", "psmTitle", "finalPricingTitle"]) {
|
|
assert.match(page, new RegExp(`title: labels\\.${label}`), `${label} must appear in the five-step navigation`);
|
|
}
|
|
assert.match(page, /\.step-indicator\s*\{/, "the page must style the shared step-indicator layout");
|
|
assert.match(page, /\.step-connector\s*\{[\s\S]*?flex:\s*0 1 40px;/, "connectors must use the compact shared spacing");
|
|
assert.match(page, /\.primary-button,\s*\.secondary-button\s*\{[\s\S]*?color:\s*#e9fbff;/, "pricing toolbar buttons must use the student dark theme");
|
|
assert.match(page, /\.primary-button\s*\{[\s\S]*?background:\s*linear-gradient/, "the primary action must use the blue gradient button style");
|
|
assert.match(page, /\.toolbar-actions\s*\{[\s\S]*?flex:\s*none;/, "toolbar actions must retain their width instead of being compressed");
|
|
|
|
const psmTheme = page.match(/\/\* PSM dark theme \*\/([\s\S]*?)<\/style>/)?.[1] || "";
|
|
assert.ok(psmTheme, "the PSM step must define its dark theme locally");
|
|
assert.match(psmTheme, /\.psm-point-section,\s*\.psm-chart-section\s*\{[\s\S]*?background:\s*rgba\(5, 35, 48, 0\.72\)/, "PSM panels must not fall back to white cards");
|
|
assert.match(psmTheme, /\.psm-table\s*\{[\s\S]*?width:\s*100%/, "the PSM table must fill its available workspace");
|
|
assert.match(psmTheme, /\.psm-table input,\s*\.psm-point-grid input\s*\{[\s\S]*?background:\s*rgba\(2, 19, 28, 0\.7\)/, "PSM inputs must use the dark form style");
|
|
|
|
console.log("Product pricing step indicator contract passed.");
|