Skip to content

Commit 2e7c006

Browse files
implement node tunnel in cli
1 parent 4669ec4 commit 2e7c006

File tree

9 files changed

+305
-51
lines changed

9 files changed

+305
-51
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"@types/cross-spawn": "^6.0.4",
3131
"@types/node": "^20.8.9",
3232
"@types/which": "^3.0.2",
33+
"@lambdatest/node-tunnel": "^4.0.9",
3334
"ajv": "^8.12.0",
3435
"ajv-errors": "^3.0.0",
3536
"axios": "^1.6.0",

src/commander/exec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ command
6363
await tasks.run(ctx);
6464
} catch (error) {
6565
ctx.log.info('\nRefer docs: https://www.lambdatest.com/support/docs/smart-visual-regression-testing/');
66+
throw new Error();
6667
}
6768
})
6869

src/lib/ctx.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Context, Env, WebConfig, MobileConfig, basicAuth } from '../types.js'
1+
import { Context, Env, WebConfig, MobileConfig, basicAuth, tunnelConfig } from '../types.js'
22
import constants from './constants.js'
33
import { version } from '../../package.json'
44
import { validateConfig } from './schemaValidation.js'
@@ -12,6 +12,7 @@ export default (options: Record<string, string>): Context => {
1212
let webConfig: WebConfig;
1313
let mobileConfig: MobileConfig;
1414
let basicAuthObj: basicAuth
15+
let tunnelObj: tunnelConfig
1516
let config = constants.DEFAULT_CONFIG;
1617
let port: number;
1718
let resolutionOff: boolean;
@@ -77,7 +78,10 @@ export default (options: Record<string, string>): Context => {
7778
}
7879
if (config.basicAuthorization) {
7980
basicAuthObj = config.basicAuthorization
80-
}
81+
}
82+
if (config.tunnel) {
83+
tunnelObj = config.tunnel
84+
}
8185

8286
return {
8387
env: env,
@@ -100,7 +104,7 @@ export default (options: Record<string, string>): Context => {
100104
useGlobalCache: config.useGlobalCache ?? false,
101105
ignoreHTTPSErrors: config.ignoreHTTPSErrors ?? false,
102106
skipBuildCreation: config.skipBuildCreation ?? false,
103-
tunnel: config.tunnel ?? false,
107+
tunnel: tunnelObj,
104108
tunnelName: config.tunnelName || ''
105109
},
106110
uploadFilePath: '',
@@ -143,6 +147,8 @@ export default (options: Record<string, string>): Context => {
143147
isSnapshotCaptured: false,
144148
sessionCapabilitiesMap: new Map<string, any[]>(),
145149
buildToSnapshotCountMap: new Map<string, number>(),
146-
fetchResultsForBuild: new Array<string>
150+
fetchResultsForBuild: new Array<string>,
151+
orgId: 0,
152+
userId: 0
147153
}
148154
}

src/lib/httpClient.ts

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,17 @@ export default class httpClient {
4545

4646
this.axiosInstance = axios.create(axiosConfig);
4747

48-
4948
this.axiosInstance.interceptors.request.use((config) => {
5049
if (!config.headers['projectToken']) {
5150
config.headers['projectToken'] = this.projectToken;
5251
}
5352
config.headers['projectName'] = this.projectName;
54-
config.headers['username'] = this.username;
55-
config.headers['accessKey'] = this.accessKey;
53+
if (!config.headers['username'] || config.headers['username'] === '') {
54+
config.headers['username'] = this.username;
55+
}
56+
if (!config.headers['accessKey'] || config.headers['accessKey'] === '') {
57+
config.headers['accessKey'] = this.accessKey;
58+
}
5659
return config;
5760
});
5861

@@ -151,6 +154,47 @@ export default class httpClient {
151154
}
152155
}
153156

157+
async authExec(ctx: Context, log: Logger, env: Env): Promise<{ authResult: number, orgId: number, userId: number }> {
158+
let authResult = 1;
159+
let userName = '';
160+
let passWord = '';
161+
if (ctx.config.tunnel?.user) {
162+
userName = ctx.config.tunnel.user
163+
}
164+
if (ctx.config.tunnel?.key) {
165+
passWord = ctx.config.tunnel.key
166+
}
167+
if (this.projectToken) {
168+
authResult = 0;
169+
}
170+
const response = await this.request({
171+
url: '/token/verify',
172+
method: 'GET',
173+
headers: {
174+
username: userName,
175+
accessKey: passWord
176+
}
177+
}, log);
178+
if (response && response.projectToken) {
179+
let orgId = 0;
180+
let userId = 0;
181+
this.projectToken = response.projectToken;
182+
env.PROJECT_TOKEN = response.projectToken;
183+
if (response.message && response.message.includes('Project created successfully')) {
184+
authResult = 2;
185+
}
186+
if (response.orgId) {
187+
orgId = response.orgId
188+
}
189+
if (response.userId) {
190+
userId = response.userId
191+
}
192+
return { authResult, orgId, userId };
193+
} else {
194+
throw new Error('Authentication failed, project token not received');
195+
}
196+
}
197+
154198
createBuild(git: Git, config: any, log: Logger, buildName: string, isStartExec: boolean) {
155199
return this.request({
156200
url: '/build',
@@ -174,12 +218,16 @@ export default class httpClient {
174218
}, log);
175219
}
176220

177-
getTunnelDetails(tunnelName: string, log: Logger) {
221+
getTunnelDetails(ctx: Context, log: Logger) {
178222
return this.request({
179223
url: '/tunnel',
180224
method: 'POST',
181225
data: {
182-
tunnelName: tunnelName
226+
tunnelName: ctx.config.tunnel?.tunnelName,
227+
orgId: ctx.orgId,
228+
userId: ctx.userId,
229+
userName: ctx.config.tunnel?.user,
230+
password: ctx.config.tunnel?.key
183231
}
184232
}, log)
185233
}

src/lib/schemaValidation.ts

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,59 @@ const ConfigSchema = {
189189
errorMessage: "Invalid config; skipBuildCreation must be true/false"
190190
},
191191
tunnel: {
192-
type: "boolean",
193-
errorMessage: "Invalid config; tunnel must be true/false"
192+
type: "object",
193+
properties: {
194+
type: {
195+
type: "string",
196+
errorMessage: "Invalid config; type is mandatory of type string"
197+
},
198+
tunnelName: {
199+
type: "string",
200+
errorMessage: "Invalid config; tunnelName should be a string value"
201+
},
202+
user: {
203+
type: "string",
204+
errorMessage: "Invalid config; user should be a string value"
205+
},
206+
key: {
207+
type: "string",
208+
errorMessage: "Invalid config; key should be a string value"
209+
},
210+
port: {
211+
type: "number",
212+
errorMessage: "Invalid config; port should be a string value"
213+
},
214+
proxyHost: {
215+
type: "string",
216+
errorMessage: "Invalid config; proxyHost should be a string value"
217+
},
218+
proxyPort: {
219+
type: "number",
220+
errorMessage: "Invalid config; proxyPort should be an int value"
221+
},
222+
proxyUser: {
223+
type: "string",
224+
errorMessage: "Invalid config; proxyUser should be a string value"
225+
},
226+
proxyPass: {
227+
type: "string",
228+
errorMessage: "Invalid config; proxyPass should be a string value"
229+
},
230+
dir: {
231+
type: "string",
232+
errorMessage: "Invalid config; dir should be a string value"
233+
},
234+
v: {
235+
type: "boolean",
236+
errorMessage: "Invalid config; v should be a boolean value"
237+
},
238+
logFile: {
239+
type: "string",
240+
errorMessage: "Invalid config; logFile should be a string value"
241+
},
242+
},
243+
required: ["type"],
244+
additionalProperties: false
194245
},
195246
tunnelName: {
196247
type: "string",

0 commit comments

Comments
 (0)