Skip to content

Commit ed8e4f9

Browse files
committed
fix: dont use env vars for time travel
1 parent 15a6254 commit ed8e4f9

File tree

4 files changed

+81
-74
lines changed

4 files changed

+81
-74
lines changed

run/test/specs/cta_donate_time.spec.ts

Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,13 @@ import { USERNAME } from '../../types/testing';
77
import { CTAButtonPositive } from './locators/global';
88
import { PlusButton } from './locators/home';
99
import { newUser } from './utils/create_account';
10-
import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from './utils/open_app';
11-
import { clearIOSCustomTimes, setIOSFirstInstallDate } from './utils/time_travel';
10+
import {
11+
closeApp,
12+
IOSTestContext,
13+
openAppOnPlatformSingleDevice,
14+
SupportedPlatformsType,
15+
} from './utils/open_app';
16+
import { setIOSFirstInstallDate } from './utils/time_travel';
1217

1318
// iOS uses app-level time override (customFirstInstallDateTime capability).
1419
// Android would require system-level time manipulation (`adb root` + `toybox date`), which
@@ -28,26 +33,24 @@ iosIt({
2833
});
2934

3035
async function donateCTAShowsSevenDaysAgo(platform: SupportedPlatformsType, testInfo: TestInfo) {
31-
setIOSFirstInstallDate({ days: -7, minutes: -2 }); // 7 days and 2 minutes ago
32-
try {
33-
const { device } = await test.step(TestSteps.SETUP.NEW_USER, async () => {
34-
const { device } = await openAppOnPlatformSingleDevice(platform, testInfo);
35-
await newUser(device, USERNAME.ALICE, { saveUserData: false });
36-
return { device };
37-
});
38-
await test.step(TestSteps.VERIFY.SPECIFIC_MODAL('Donate CTA'), async () => {
39-
await device.checkCTAStrings(
40-
englishStrippedStr('donateSessionHelp').toString(),
41-
englishStrippedStr('donateSessionDescription').toString(),
42-
[englishStrippedStr('donate').toString(), englishStrippedStr('maybeLater').toString()]
43-
);
44-
});
45-
await test.step(TestSteps.SETUP.CLOSE_APP, async () => {
46-
await closeApp(device);
47-
});
48-
} finally {
49-
clearIOSCustomTimes();
50-
}
36+
const iosContext: IOSTestContext = {
37+
customInstallTime: setIOSFirstInstallDate({ days: -7, minutes: -2 }),
38+
};
39+
const { device } = await test.step(TestSteps.SETUP.NEW_USER, async () => {
40+
const { device } = await openAppOnPlatformSingleDevice(platform, testInfo, iosContext);
41+
await newUser(device, USERNAME.ALICE, { saveUserData: false });
42+
return { device };
43+
});
44+
await test.step(TestSteps.VERIFY.SPECIFIC_MODAL('Donate CTA'), async () => {
45+
await device.checkCTAStrings(
46+
englishStrippedStr('donateSessionHelp').toString(),
47+
englishStrippedStr('donateSessionDescription').toString(),
48+
[englishStrippedStr('donate').toString(), englishStrippedStr('maybeLater').toString()]
49+
);
50+
});
51+
await test.step(TestSteps.SETUP.CLOSE_APP, async () => {
52+
await closeApp(device);
53+
});
5154
}
5255

5356
iosIt({
@@ -63,23 +66,21 @@ iosIt({
6366
});
6467

6568
async function donateCTADoesntShowSixDaysAgo(platform: SupportedPlatformsType, testInfo: TestInfo) {
66-
setIOSFirstInstallDate({ days: -6, hours: -23, minutes: -58 }); // 6 days, 23 hours, and 58 minutes ago
67-
try {
68-
const { device } = await test.step(TestSteps.SETUP.NEW_USER, async () => {
69-
const { device } = await openAppOnPlatformSingleDevice(platform, testInfo);
70-
await newUser(device, USERNAME.ALICE, { saveUserData: false });
71-
return { device };
72-
});
73-
await test.step('Verify Donate CTA does not show', async () => {
74-
await Promise.all([
75-
device.waitForTextElementToBePresent(new PlusButton(device)),
76-
device.verifyElementNotPresent(new CTAButtonPositive(device)),
77-
]);
78-
});
79-
await test.step(TestSteps.SETUP.CLOSE_APP, async () => {
80-
await closeApp(device);
81-
});
82-
} finally {
83-
clearIOSCustomTimes();
84-
}
69+
const iosContext: IOSTestContext = {
70+
customInstallTime: setIOSFirstInstallDate({ days: -6, hours: -23, minutes: -58 }),
71+
};
72+
const { device } = await test.step(TestSteps.SETUP.NEW_USER, async () => {
73+
const { device } = await openAppOnPlatformSingleDevice(platform, testInfo, iosContext);
74+
await newUser(device, USERNAME.ALICE, { saveUserData: false });
75+
return { device };
76+
});
77+
await test.step('Verify Donate CTA does not show', async () => {
78+
await Promise.all([
79+
device.waitForTextElementToBePresent(new PlusButton(device)),
80+
device.verifyElementNotPresent(new CTAButtonPositive(device)),
81+
]);
82+
});
83+
await test.step(TestSteps.SETUP.CLOSE_APP, async () => {
84+
await closeApp(device);
85+
});
8586
}

run/test/specs/utils/capabilities_ios.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,10 @@ export function capabilityIsValid(
122122
return true;
123123
}
124124

125-
export function getIosCapabilities(capabilitiesIndex: CapabilitiesIndexType): W3CCapabilities {
125+
export function getIosCapabilities(
126+
capabilitiesIndex: CapabilitiesIndexType,
127+
customInstallTime?: string
128+
): W3CCapabilities {
126129
if (capabilitiesIndex >= capabilities.length) {
127130
throw new Error(
128131
`Asked invalid ios cap index: ${capabilitiesIndex}. Number of iOS capabilities: ${capabilities.length}.`
@@ -140,8 +143,7 @@ export function getIosCapabilities(capabilitiesIndex: CapabilitiesIndexType): W3
140143
// Optional per-test override:
141144
// Some tests set IOS_CUSTOM_FIRST_INSTALL_DATE_TIME before starting Appium.
142145
// If present, inject it into the processArguments.env. Otherwise inject nothing.
143-
const custom = process.env.IOS_CUSTOM_FIRST_INSTALL_DATE_TIME;
144-
const customEnv = custom ? { customFirstInstallDateTime: custom } : {};
146+
const customEnv = customInstallTime ? { customFirstInstallDateTime: customInstallTime } : {};
145147

146148
// Rebuild the processArguments block with merged env vars
147149
caps['appium:processArguments'] = {

run/test/specs/utils/open_app.ts

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,19 @@ const APPIUM_PORT = 4728;
2424

2525
export type SupportedPlatformsType = 'android' | 'ios';
2626

27+
export type IOSTestContext = {
28+
customInstallTime?: string;
29+
};
30+
2731
export const openAppMultipleDevices = async (
2832
platform: SupportedPlatformsType,
2933
numberOfDevices: number,
30-
testInfo: TestInfo
34+
testInfo: TestInfo,
35+
iOSContext?: IOSTestContext
3136
): Promise<DeviceWrapper[]> => {
3237
// Create an array of promises for each device
3338
const devicePromises = Array.from({ length: numberOfDevices }, (_, index) =>
34-
openAppOnPlatform(platform, index as CapabilitiesIndexType, testInfo)
39+
openAppOnPlatform(platform, index as CapabilitiesIndexType, testInfo, iOSContext)
3540
);
3641

3742
// Use Promise.all to wait for all device apps to open
@@ -48,23 +53,25 @@ export const openAppMultipleDevices = async (
4853
const openAppOnPlatform = async (
4954
platform: SupportedPlatformsType,
5055
capabilitiesIndex: CapabilitiesIndexType,
51-
testInfo: TestInfo
56+
testInfo: TestInfo,
57+
iOSContext?: IOSTestContext
5258
): Promise<{
5359
device: DeviceWrapper;
5460
}> => {
5561
console.info('starting capabilitiesIndex', capabilitiesIndex, platform);
5662
return platform === 'ios'
57-
? openiOSApp(capabilitiesIndex, testInfo)
63+
? openiOSApp(capabilitiesIndex, testInfo, iOSContext)
5864
: openAndroidApp(capabilitiesIndex, testInfo);
5965
};
6066

6167
export const openAppOnPlatformSingleDevice = async (
6268
platform: SupportedPlatformsType,
63-
testInfo: TestInfo
69+
testInfo: TestInfo,
70+
iOSContext?: IOSTestContext
6471
): Promise<{
6572
device: DeviceWrapper;
6673
}> => {
67-
const result = await openAppOnPlatform(platform, 0, testInfo);
74+
const result = await openAppOnPlatform(platform, 0, testInfo, iOSContext);
6875

6976
registerDevicesForTest(testInfo, [result.device], platform);
7077

@@ -73,14 +80,15 @@ export const openAppOnPlatformSingleDevice = async (
7380

7481
export const openAppTwoDevices = async (
7582
platform: SupportedPlatformsType,
76-
testInfo: TestInfo
83+
testInfo: TestInfo,
84+
iOSContext?: IOSTestContext
7785
): Promise<{
7886
device1: DeviceWrapper;
7987
device2: DeviceWrapper;
8088
}> => {
8189
const [app1, app2] = await Promise.all([
82-
openAppOnPlatform(platform, 0, testInfo),
83-
openAppOnPlatform(platform, 1, testInfo),
90+
openAppOnPlatform(platform, 0, testInfo, iOSContext),
91+
openAppOnPlatform(platform, 1, testInfo, iOSContext),
8492
]);
8593

8694
const result = { device1: app1.device, device2: app2.device };
@@ -92,16 +100,17 @@ export const openAppTwoDevices = async (
92100

93101
export const openAppThreeDevices = async (
94102
platform: SupportedPlatformsType,
95-
testInfo: TestInfo
103+
testInfo: TestInfo,
104+
iOSContext?: IOSTestContext
96105
): Promise<{
97106
device1: DeviceWrapper;
98107
device2: DeviceWrapper;
99108
device3: DeviceWrapper;
100109
}> => {
101110
const [app1, app2, app3] = await Promise.all([
102-
openAppOnPlatform(platform, 0, testInfo),
103-
openAppOnPlatform(platform, 1, testInfo),
104-
openAppOnPlatform(platform, 2, testInfo),
111+
openAppOnPlatform(platform, 0, testInfo, iOSContext),
112+
openAppOnPlatform(platform, 1, testInfo, iOSContext),
113+
openAppOnPlatform(platform, 2, testInfo, iOSContext),
105114
]);
106115

107116
const result = {
@@ -117,18 +126,19 @@ export const openAppThreeDevices = async (
117126

118127
export const openAppFourDevices = async (
119128
platform: SupportedPlatformsType,
120-
testInfo: TestInfo
129+
testInfo: TestInfo,
130+
iOSContext?: IOSTestContext
121131
): Promise<{
122132
device1: DeviceWrapper;
123133
device2: DeviceWrapper;
124134
device3: DeviceWrapper;
125135
device4: DeviceWrapper;
126136
}> => {
127137
const [app1, app2, app3, app4] = await Promise.all([
128-
openAppOnPlatform(platform, 0, testInfo),
129-
openAppOnPlatform(platform, 1, testInfo),
130-
openAppOnPlatform(platform, 2, testInfo),
131-
openAppOnPlatform(platform, 3, testInfo),
138+
openAppOnPlatform(platform, 0, testInfo, iOSContext),
139+
openAppOnPlatform(platform, 1, testInfo, iOSContext),
140+
openAppOnPlatform(platform, 2, testInfo, iOSContext),
141+
openAppOnPlatform(platform, 3, testInfo, iOSContext),
132142
]);
133143

134144
const result = {
@@ -286,7 +296,8 @@ const openAndroidApp = async (
286296

287297
const openiOSApp = async (
288298
capabilitiesIndex: CapabilitiesIndexType,
289-
testInfo: TestInfo
299+
testInfo: TestInfo,
300+
iOSContext?: IOSTestContext
290301
): Promise<{
291302
device: DeviceWrapper;
292303
}> => {
@@ -321,7 +332,10 @@ const openiOSApp = async (
321332
address: `http://localhost:${APPIUM_PORT}`,
322333
} as XCUITestDriverOpts;
323334

324-
const capabilities = getIosCapabilities(actualCapabilitiesIndex as CapabilitiesIndexType);
335+
const capabilities = getIosCapabilities(
336+
actualCapabilitiesIndex as CapabilitiesIndexType,
337+
iOSContext?.customInstallTime
338+
);
325339
const udid = capabilities.alwaysMatch['appium:udid'] as string;
326340

327341
const { device: wrappedDevice } = await cleanPermissions(opts, udid, capabilities, testInfo);

run/test/specs/utils/time_travel.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,6 @@ function applyTimeOffset(offset: TimeOffset): { date: Date; timestamp: string }
2727
*/
2828
export function setIOSFirstInstallDate(offset: TimeOffset): string {
2929
const { date, timestamp } = applyTimeOffset(offset);
30-
process.env.IOS_CUSTOM_FIRST_INSTALL_DATE_TIME = timestamp;
31-
3230
console.log(`Mocking iOS first install date: ${timestamp} (${date.toLocaleString('en-AU')})`);
3331
return timestamp;
3432
}
35-
36-
/**
37-
* Clear both custom time environment variables
38-
*/
39-
export function clearIOSCustomTimes(): void {
40-
delete process.env.IOS_CUSTOM_FIRST_INSTALL_DATE_TIME;
41-
console.log('iOS custom install time cleared');
42-
}

0 commit comments

Comments
 (0)