mirror of
https://github.com/Alvin-Zilverstand/return-youtube-dislike.git
synced 2026-09-12 09:58:20 +02:00
e500088e65
Add Firefox data consent, repair contributor sign-in, and introduce optional Hide clutter buttons. Harden video navigation, voting, and action layouts with shared browser regression coverage and reproducible release packaging.
128 lines
3.4 KiB
JavaScript
128 lines
3.4 KiB
JavaScript
const WATCH_VISUAL_RUNTIMES = Object.freeze(["userscript", "extension"]);
|
|
|
|
const WATCH_VISUAL_VIEWPORTS = Object.freeze([
|
|
Object.freeze({ name: "wide", width: 1280, height: 720 }),
|
|
Object.freeze({ name: "narrow", width: 768, height: 720 }),
|
|
Object.freeze({ name: "compact", width: 390, height: 844 }),
|
|
]);
|
|
|
|
const WATCH_REACTION_TRANSITIONS = Object.freeze([
|
|
Object.freeze({
|
|
action: "like",
|
|
initialState: "neutral",
|
|
nextState: "liked",
|
|
value: 1,
|
|
likesDelta: 1,
|
|
dislikesDelta: 0,
|
|
}),
|
|
Object.freeze({
|
|
action: "dislike",
|
|
initialState: "neutral",
|
|
nextState: "disliked",
|
|
value: -1,
|
|
likesDelta: 0,
|
|
dislikesDelta: 1,
|
|
}),
|
|
Object.freeze({
|
|
action: "like",
|
|
initialState: "liked",
|
|
nextState: "neutral",
|
|
value: 0,
|
|
likesDelta: -1,
|
|
dislikesDelta: 0,
|
|
}),
|
|
Object.freeze({
|
|
action: "dislike",
|
|
initialState: "liked",
|
|
nextState: "disliked",
|
|
value: -1,
|
|
likesDelta: -1,
|
|
dislikesDelta: 1,
|
|
}),
|
|
Object.freeze({
|
|
action: "like",
|
|
initialState: "disliked",
|
|
nextState: "liked",
|
|
value: 1,
|
|
likesDelta: 1,
|
|
dislikesDelta: -1,
|
|
}),
|
|
Object.freeze({
|
|
action: "dislike",
|
|
initialState: "disliked",
|
|
nextState: "neutral",
|
|
value: 0,
|
|
likesDelta: 0,
|
|
dislikesDelta: -1,
|
|
}),
|
|
]);
|
|
|
|
const WATCH_VISUAL_SCENARIOS = Object.freeze(
|
|
WATCH_VISUAL_VIEWPORTS.flatMap((viewport) =>
|
|
WATCH_REACTION_TRANSITIONS.map((transition) =>
|
|
Object.freeze({
|
|
id: `watch-${viewport.name}-${transition.initialState}-${transition.action}-${transition.nextState}`,
|
|
transition,
|
|
viewport,
|
|
}),
|
|
),
|
|
),
|
|
);
|
|
|
|
const WATCH_VISUAL_RUNTIME_REGISTRATIONS = Object.freeze(
|
|
Object.fromEntries(
|
|
WATCH_VISUAL_RUNTIMES.map((runtime) => [
|
|
runtime,
|
|
Object.freeze({
|
|
runtime,
|
|
scenarioIds: Object.freeze(WATCH_VISUAL_SCENARIOS.map(({ id }) => id)),
|
|
}),
|
|
]),
|
|
),
|
|
);
|
|
|
|
function getWatchVisualRuntimeRegistration(runtime) {
|
|
const registration = WATCH_VISUAL_RUNTIME_REGISTRATIONS[runtime];
|
|
if (!registration) throw new TypeError(`Unsupported Watch visual runtime: ${runtime}`);
|
|
return registration;
|
|
}
|
|
|
|
function getWatchNeutralBaselineId(scenario) {
|
|
if (!scenario?.transition || !scenario?.viewport) {
|
|
throw new TypeError("A Watch visual scenario is required.");
|
|
}
|
|
return scenario.transition.initialState === "neutral" && scenario.transition.action === "like"
|
|
? `watch-${scenario.viewport.name}-neutral`
|
|
: null;
|
|
}
|
|
|
|
function registerWatchVisualContract({ runScenario, runtime, test }) {
|
|
if (typeof test !== "function" || typeof test.describe !== "function") {
|
|
throw new TypeError("The Watch visual contract requires a Playwright-compatible test function.");
|
|
}
|
|
if (typeof runScenario !== "function") {
|
|
throw new TypeError("The Watch visual contract requires runScenario().");
|
|
}
|
|
|
|
const registration = getWatchVisualRuntimeRegistration(runtime);
|
|
test.describe(`${runtime} Watch visual contract`, () => {
|
|
for (const scenario of WATCH_VISUAL_SCENARIOS) {
|
|
test(scenario.id, async ({ context, page }, testInfo) =>
|
|
runScenario({ fixtures: { context, page }, registration, scenario, testInfo }),
|
|
);
|
|
}
|
|
});
|
|
return registration;
|
|
}
|
|
|
|
module.exports = {
|
|
WATCH_REACTION_TRANSITIONS,
|
|
WATCH_VISUAL_RUNTIMES,
|
|
WATCH_VISUAL_RUNTIME_REGISTRATIONS,
|
|
WATCH_VISUAL_SCENARIOS,
|
|
WATCH_VISUAL_VIEWPORTS,
|
|
getWatchNeutralBaselineId,
|
|
getWatchVisualRuntimeRegistration,
|
|
registerWatchVisualContract,
|
|
};
|