This repository has been archived by the owner on Nov 13, 2024. It is now read-only.
forked from fschoenfeldt/detox-expo-helpers
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
156 lines (135 loc) · 4.43 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
const { UrlUtils } = require("xdl");
const cp = require("child_process");
const fs = require("fs");
const os = require("os");
const path = require("path");
const semver = require("semver");
const OSX_APP_PATH = path.join(os.homedir(), "Library");
const OSX_LIBRARY_ROOT_PATH = path.join(OSX_APP_PATH, "ExpoDetoxHook");
const expoDetoxHookAppPath = path.join(
process.cwd(),
"node_modules/expo-detox-hook"
);
const expoDetoxHookPackageJsonPath = path.join(
expoDetoxHookAppPath,
"package.json"
);
function getFrameworkPath() {
const version = require(expoDetoxHookPackageJsonPath).version;
let sha1 = cp
.execSync(
`(echo "${version}" && xcodebuild -version) | shasum | awk '{print $1}'`
)
.toString()
.trim();
return `${OSX_LIBRARY_ROOT_PATH}/ios/${sha1}/ExpoDetoxHook.framework/ExpoDetoxHook`;
}
let url;
const getAppUrl = async () => {
if (!url) {
url = await UrlUtils.constructManifestUrlAsync(process.cwd());
}
return url;
};
const getAppHttpUrl = async () => {
const httpUrl = await UrlUtils.constructUrlAsync(
process.cwd(),
{ urlType: "http" },
true
);
return httpUrl;
};
function resetEnvDyldVar(oldEnvVar) {
if (oldEnvVar) {
// revert the env var to the old value
process.env.SIMCTL_CHILD_DYLD_INSERT_LIBRARIES = oldVar;
} else {
// old env var was never defined, so we delete it
delete process.env.SIMCTL_CHILD_DYLD_INSERT_LIBRARIES;
}
}
const reloadApp = async (params) => {
if (!fs.existsSync(expoDetoxHookPackageJsonPath)) {
throw new Error(
"expo-detox-hook is not installed in this directory. You should declare it in package.json and run `npm install`"
);
}
const expoDetoxHookFrameworkPath = getFrameworkPath();
if (!fs.existsSync(expoDetoxHookFrameworkPath)) {
throw new Error(
"expo-detox-hook is not installed in your osx Library. Run `npm install -g expo-detox-cli && expotox clean-framework-cache && expotox build-framework-cache` to fix this."
);
}
const detoxVersion = getDetoxVersion();
const oldEnvVar = process.env.SIMCTL_CHILD_DYLD_INSERT_LIBRARIES;
if (semver.gte(detoxVersion, "9.0.6")) {
process.env.SIMCTL_CHILD_DYLD_INSERT_LIBRARIES = expoDetoxHookFrameworkPath;
}
const formattedBlacklistArg = await blacklistCmdlineFormat(
params && params.urlBlacklist
);
const url = await getAppUrl();
await device.launchApp({
permissions: params && params.permissions,
newInstance: true,
url,
sourceApp: "host.exp.exponent",
launchArgs: {
EXKernelDisableNuxDefaultsKey: true,
detoxURLBlacklistRegex: formattedBlacklistArg,
detoxEnableSynchronization: 0,
...(params && params.launchArgs),
},
...(params && params.args),
});
if (semver.lt(detoxVersion, "9.0.6")) {
// we will need to pass in blacklist again before it was supported at init in 9.0.6
await blacklistLiveReloadUrl(params && params.urlBlacklist);
} else {
resetEnvDyldVar(oldEnvVar);
}
};
const getDetoxVersion = () => {
const detoxPackageJsonPath = path.join(
process.cwd(),
"node_modules/detox/package.json"
);
if (!fs.existsSync(detoxPackageJsonPath)) {
throw new Error(
`detox is not installed in this directory: ${detoxPackageJsonPath}`
);
}
return require(detoxPackageJsonPath).version;
};
function escapeRegExp(str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}
const getBlacklist = async () => {
const httpUrl = await getAppHttpUrl();
const liveReloadUrl = `${httpUrl}/onchange`;
const fabricUrl = "https://e.crashlytics.com/spi/v2/events";
return [liveReloadUrl, fabricUrl];
};
// returns blacklist arg in format like \\("http://192.168.1.253:19001/onchange","https://e.crashlytics.com/spi/v2/events"\\)
const blacklistCmdlineFormat = async (userBlacklist) => {
const expoBlacklist = await getBlacklist();
const blacklist = userBlacklist
? expoBlacklist.concat(userBlacklist)
: expoBlacklist;
const cmdlineFormatBlacklist = blacklist.map((url) => `"${url}"`).join(",");
return `\\(${cmdlineFormatBlacklist}\\)`;
};
const blacklistLiveReloadUrl = async (userBlacklist) => {
const expoBlacklist = await getBlacklist();
const blacklist = userBlacklist
? expoBlacklist.concat(userBlacklist)
: expoBlacklist;
const regexBlacklist = blacklist.map((url) => escapeRegExp(url));
await device.setURLBlacklist(regexBlacklist);
};
module.exports = {
getAppUrl,
getAppHttpUrl,
blacklistLiveReloadUrl,
reloadApp,
};