fix: flaky plan e2e test (#27349)

This commit is contained in:
Michael Geers 2026-02-11 10:43:53 +01:00 • committed by GitHub
parent 90e7ac313f
commit c16ef73090
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 45 additions and 23 deletions

View file

@ -80,8 +80,9 @@ import collector from "@/mixins/collector";
import api from "@/api";
import deepEqual from "@/utils/deepEqual";
import convertRates from "@/utils/convertRates";
import { debounceLeading } from "@/utils/debounceLeading";
import { defineComponent, type PropType } from "vue";
import type { Vehicle, Timeout, CURRENCY, Forecast } from "@/types/evcc";
import type { Vehicle, CURRENCY, Forecast } from "@/types/evcc";
import type {
StaticPlan,
RepeatingPlan,
@ -135,9 +136,10 @@ export default defineComponent({
staticPlanPreview: {} as StaticPlan,
plan: {} as PlanWrapper,
activeTab: "time",
debounceTimer: null as Timeout,
nextPlanId: 0,
strategyOpen: false,
updatePlanPreviewDebounced: null as any as () => void,
updateActivePlanDebounced: null as any as () => void,
};
},
computed: {
@ -182,8 +184,10 @@ export default defineComponent({
},
effectivePlanStrategy: {
deep: true,
handler() {
this.updatePlanDebounced();
handler(vNew: PlanStrategy, vOld: PlanStrategy) {
if (!deepEqual(vNew, vOld)) {
this.updatePlanDebounced();
}
},
},
staticPlan: {
@ -204,14 +208,22 @@ export default defineComponent({
},
},
mounted(): void {
this.updatePlanPreviewDebounced = debounceLeading(
async () => await this.updatePreviewPlan(),
300
);
this.updateActivePlanDebounced = debounceLeading(
async () => await this.updateActivePlan(),
300
);
this.updatePlanDebounced();
},
methods: {
async updatePlanDebounced() {
updatePlanDebounced(): void {
if (this.noActivePlan) {
await this.updatePlanPreviewDebounced();
this.updatePlanPreviewDebounced();
} else {
await this.updateActivePlanDebounced();
this.updateActivePlanDebounced();
}
},
async updateActivePlan(): Promise<void> {
@ -285,22 +297,6 @@ export default defineComponent({
console.error(e);
}
},
async updatePlanPreviewDebounced(): Promise<void> {
if (!this.debounceTimer) {
await this.updatePreviewPlan();
return;
}
clearTimeout(this.debounceTimer);
this.debounceTimer = setTimeout(async () => await this.updatePreviewPlan(), 1000);
},
async updateActivePlanDebounced(): Promise<void> {
if (!this.debounceTimer) {
await this.updateActivePlan();
return;
}
clearTimeout(this.debounceTimer);
this.debounceTimer = setTimeout(async () => await this.updateActivePlan(), 1000);
},
removeStaticPlan(): void {
this.$emit("static-plan-removed");
},

View file

@ -0,0 +1,26 @@
import type { Timeout } from "@/types/evcc";
/**
* Creates a debounced version of `fn` that calls at the leading edge.
* The debounced function does not return the result of `fn`, even if `fn` is async.
*/
export function debounceLeading<T extends (...args: any[]) => any>(
fn: T,
delay: number
): (...args: Parameters<T>) => void {
let timer: Timeout;
return (...args: Parameters<T>) => {
if (!timer) {
fn(...args);
timer = setTimeout(() => {
timer = null;
}, delay);
return;
}
clearTimeout(timer);
timer = setTimeout(() => {
timer = null;
fn(...args);
}, delay);
};
}