Skip to content

Commit

Permalink
Merge pull request #37126 from VickyStash/ts-migration/index-test
Browse files Browse the repository at this point in the history
[No QA] [TS migration] Migrate 'index.js' test to TypeScript
  • Loading branch information
tgolen authored Feb 28, 2024
2 parents fef79df + 7d53f28 commit 3100b18
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 49 deletions.
10 changes: 10 additions & 0 deletions src/libs/E2E/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,19 @@ import Routes from '../../../tests/e2e/server/routes';
import type {NetworkCacheMap, TestConfig} from './types';

type TestResult = {
/** Name of the test */
name: string;

/** The branch where test were running */
branch?: string;

/** Duration in milliseconds */
duration?: number;

/** Optional, if set indicates that the test run failed and has no valid results. */
error?: string;

/** Render count */
renderCount?: number;
};

Expand Down Expand Up @@ -113,3 +122,4 @@ export default {
updateNetworkCache,
getNetworkCache,
};
export type {TestResult, NativeCommand};
108 changes: 59 additions & 49 deletions tests/e2e/server/index.js → tests/e2e/server/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,42 @@
import {createServer} from 'http';
import type {IncomingMessage, ServerResponse} from 'http';
import type {NativeCommand, TestResult} from '@libs/E2E/client';
import type {NetworkCacheMap, TestConfig} from '@libs/E2E/types';
import config from '../config';
import * as nativeCommands from '../nativeCommands';
import * as Logger from '../utils/logger';
import Routes from './routes';

const PORT = process.env.PORT || config.SERVER_PORT;
type NetworkCache = {
appInstanceId: string;
cache: NetworkCacheMap;
};

type RequestData = TestResult | NativeCommand | NetworkCache;

type TestStartedListener = (testConfig?: TestConfig) => void;

type TestDoneListener = () => void;

type TestResultListener = (testResult: TestResult) => void;

type AddListener<TListener> = (listener: TListener) => void;

type ServerInstance = {
setTestConfig: (testConfig: TestConfig) => void;
addTestStartedListener: AddListener<TestStartedListener>;
addTestResultListener: AddListener<TestResultListener>;
addTestDoneListener: AddListener<TestDoneListener>;
start: () => Promise<void>;
stop: () => Promise<Error | undefined>;
};

const PORT = process.env.PORT ?? config.SERVER_PORT;

// Gets the request data as a string
const getReqData = (req) => {
const getReqData = (req: IncomingMessage): Promise<string> => {
let data = '';
req.on('data', (chunk) => {
req.on('data', (chunk: string) => {
data += chunk;
});

Expand All @@ -21,16 +48,16 @@ const getReqData = (req) => {
};

// Expects a POST request with JSON data. Returns parsed JSON data.
const getPostJSONRequestData = (req, res) => {
const getPostJSONRequestData = <TRequestData extends RequestData>(req: IncomingMessage, res: ServerResponse<IncomingMessage>): Promise<TRequestData | undefined> | undefined => {
if (req.method !== 'POST') {
res.statusCode = 400;
res.end('Unsupported method');
return;
}

return getReqData(req).then((data) => {
return getReqData(req).then((data): TRequestData | undefined => {
try {
return JSON.parse(data);
return JSON.parse(data) as TRequestData;
} catch (e) {
Logger.info('❌ Failed to parse request data', data);
res.statusCode = 400;
Expand All @@ -39,9 +66,9 @@ const getPostJSONRequestData = (req, res) => {
});
};

const createListenerState = () => {
const listeners = [];
const addListener = (listener) => {
const createListenerState = <TListener>(): [TListener[], AddListener<TListener>] => {
const listeners: TListener[] = [];
const addListener = (listener: TListener) => {
listeners.push(listener);
return () => {
const index = listeners.indexOf(listener);
Expand All @@ -54,20 +81,6 @@ const createListenerState = () => {
return [listeners, addListener];
};

/**
* The test result object that a client might submit to the server.
* @typedef TestResult
* @property {string} name
* @property {number} duration Milliseconds
* @property {string} [error] Optional, if set indicates that the test run failed and has no valid results.
*/

/**
* @callback listener
* @param {TestResult} testResult
*/

// eslint-disable-next-line valid-jsdoc
/**
* Creates a new http server.
* The server just has two endpoints:
Expand All @@ -78,35 +91,32 @@ const createListenerState = () => {
*
* It returns an instance to which you can add listeners for the test results, and test done events.
*/
const createServerInstance = () => {
const [testStartedListeners, addTestStartedListener] = createListenerState();
const [testResultListeners, addTestResultListener] = createListenerState();
const [testDoneListeners, addTestDoneListener] = createListenerState();

let activeTestConfig;
const networkCache = {};

/**
* @param {TestConfig} testConfig
*/
const setTestConfig = (testConfig) => {
const createServerInstance = (): ServerInstance => {
const [testStartedListeners, addTestStartedListener] = createListenerState<TestStartedListener>();
const [testResultListeners, addTestResultListener] = createListenerState<TestResultListener>();
const [testDoneListeners, addTestDoneListener] = createListenerState<TestDoneListener>();

let activeTestConfig: TestConfig | undefined;
const networkCache: Record<string, NetworkCacheMap> = {};

const setTestConfig = (testConfig: TestConfig) => {
activeTestConfig = testConfig;
};

const server = createServer((req, res) => {
const server = createServer((req, res): ServerResponse<IncomingMessage> | void => {
res.statusCode = 200;
switch (req.url) {
case Routes.testConfig: {
testStartedListeners.forEach((listener) => listener(activeTestConfig));
if (activeTestConfig == null) {
if (!activeTestConfig) {
throw new Error('No test config set');
}
return res.end(JSON.stringify(activeTestConfig));
}

case Routes.testResults: {
getPostJSONRequestData(req, res).then((data) => {
if (data == null) {
getPostJSONRequestData<TestResult>(req, res)?.then((data) => {
if (!data) {
// The getPostJSONRequestData function already handled the response
return;
}
Expand All @@ -128,9 +138,9 @@ const createServerInstance = () => {
}

case Routes.testNativeCommand: {
getPostJSONRequestData(req, res)
.then((data) =>
nativeCommands.executeFromPayload(data.actionName, data.payload).then((status) => {
getPostJSONRequestData<NativeCommand>(req, res)
?.then((data) =>
nativeCommands.executeFromPayload(data?.actionName, data?.payload).then((status) => {
if (status) {
res.end('ok');
return;
Expand All @@ -148,8 +158,8 @@ const createServerInstance = () => {
}

case Routes.testGetNetworkCache: {
getPostJSONRequestData(req, res).then((data) => {
const appInstanceId = data && data.appInstanceId;
getPostJSONRequestData<NetworkCache>(req, res)?.then((data) => {
const appInstanceId = data?.appInstanceId;
if (!appInstanceId) {
res.statusCode = 400;
res.end('Invalid request missing appInstanceId');
Expand All @@ -164,9 +174,9 @@ const createServerInstance = () => {
}

case Routes.testUpdateNetworkCache: {
getPostJSONRequestData(req, res).then((data) => {
const appInstanceId = data && data.appInstanceId;
const cache = data && data.cache;
getPostJSONRequestData<NetworkCache>(req, res)?.then((data) => {
const appInstanceId = data?.appInstanceId;
const cache = data?.cache;
if (!appInstanceId || !cache) {
res.statusCode = 400;
res.end('Invalid request missing appInstanceId or cache');
Expand All @@ -192,11 +202,11 @@ const createServerInstance = () => {
addTestResultListener,
addTestDoneListener,
start: () =>
new Promise((resolve) => {
new Promise<void>((resolve) => {
server.listen(PORT, resolve);
}),
stop: () =>
new Promise((resolve) => {
new Promise<Error | undefined>((resolve) => {
server.close(resolve);
}),
};
Expand Down

0 comments on commit 3100b18

Please sign in to comment.