Files
wehub-resource-sync dbe3ade0dc
Enforce Pull-Request Rules / check (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:19:24 +08:00

109 lines
4.0 KiB
JavaScript

const fs = require("node:fs");
const path = require("node:path");
const weatherUtils = require("../../../defaultmodules/weather/provider-utils");
const helpers = require("./global-setup");
/**
* Inject mock weather data directly via socket communication
* This bypasses the weather provider and tests only client-side rendering
* @param {object} page - Playwright page
* @param {string} mockDataFile - Filename of mock data
*/
async function injectMockWeatherData (page, mockDataFile) {
const rawData = JSON.parse(fs.readFileSync(path.resolve(__dirname, "../../mocks", mockDataFile)).toString());
// Validate that the fixture has at least one expected weather data type
if (!rawData.current && !rawData.daily && !rawData.hourly) {
throw new Error(
"Invalid weather fixture: missing current, daily, and hourly data. "
+ `Available keys: ${Object.keys(rawData).join(", ")}`
);
}
// Determine weather type from the mock data structure
let type = "current";
let data = null;
const timezoneOffset = rawData.timezone_offset ? rawData.timezone_offset / 60 : 0;
if (rawData.current) {
type = "current";
// Mock what the provider would send for current weather
data = {
date: weatherUtils.applyTimezoneOffset(new Date(rawData.current.dt * 1000), timezoneOffset),
windSpeed: rawData.current.wind_speed,
windFromDirection: rawData.current.wind_deg,
sunrise: weatherUtils.applyTimezoneOffset(new Date(rawData.current.sunrise * 1000), timezoneOffset),
sunset: weatherUtils.applyTimezoneOffset(new Date(rawData.current.sunset * 1000), timezoneOffset),
temperature: rawData.current.temp,
weatherType: weatherUtils.convertWeatherType(rawData.current.weather[0].icon),
humidity: rawData.current.humidity,
feelsLikeTemp: rawData.current.feels_like
};
} else if (rawData.daily) {
type = "forecast";
data = rawData.daily.map((day) => ({
date: weatherUtils.applyTimezoneOffset(new Date(day.dt * 1000), timezoneOffset),
minTemperature: day.temp.min,
maxTemperature: day.temp.max,
weatherType: weatherUtils.convertWeatherType(day.weather[0].icon),
rain: day.rain || 0,
snow: day.snow || 0,
precipitationAmount: (day.rain || 0) + (day.snow || 0)
}));
} else if (rawData.hourly) {
type = "hourly";
data = rawData.hourly.map((hour) => ({
date: weatherUtils.applyTimezoneOffset(new Date(hour.dt * 1000), timezoneOffset),
temperature: hour.temp,
feelsLikeTemp: hour.feels_like,
humidity: hour.humidity,
windSpeed: hour.wind_speed,
windFromDirection: hour.wind_deg,
weatherType: weatherUtils.convertWeatherType(hour.weather[0].icon),
precipitationProbability: hour.pop != null ? hour.pop * 100 : undefined,
precipitationAmount: (hour.rain?.["1h"] || 0) + (hour.snow?.["1h"] || 0)
}));
}
// Inject weather data by evaluating code in the browser context
await page.evaluate(({ type, data }) => {
// Find the weather module instance
const weatherModule = MM.getModules().find((m) => m.name === "weather");
if (weatherModule) {
// Send INITIALIZED first
weatherModule.socketNotificationReceived("WEATHER_INITIALIZED", {
instanceId: weatherModule.instanceId,
locationName: "Munich"
});
// Then send the actual data
weatherModule.socketNotificationReceived("WEATHER_DATA", {
instanceId: weatherModule.instanceId,
type: type,
data: data
});
}
}, { type, data });
}
exports.startApplication = async (configFileName, mockDataFile) => {
await helpers.startApplication(configFileName);
await helpers.getDocument();
// If mock data file is provided, inject it
if (mockDataFile) {
const page = helpers.getPage();
// Wait for weather module to initialize
// eslint-disable-next-line playwright/no-wait-for-selector
await page.waitForSelector(".weather", { timeout: 5000 });
await injectMockWeatherData(page, mockDataFile);
// Wait for data to be rendered
// eslint-disable-next-line playwright/no-wait-for-selector
await page.waitForSelector(".weather .weathericon", { timeout: 2000 });
}
};
exports.stopApplication = async () => {
await helpers.stopApplication();
};