@lambdatest/smartui-cli 4.1.41 → 4.1.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.cjs +134 -18
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -112,7 +112,7 @@ var __async = (__this, __arguments, generator) => {
112
112
 
113
113
  // node_modules/.pnpm/find-free-port@2.0.0/node_modules/find-free-port/index.js
114
114
  var require_find_free_port = __commonJS({
115
- "node_modules/.pnpm/find-free-port@2.0.0/node_modules/find-free-port/index.js"(exports, module) {
115
+ "node_modules/.pnpm/find-free-port@2.0.0/node_modules/find-free-port/index.js"(exports$1, module) {
116
116
  var net = __require("net");
117
117
  function findFreePort(beg, ...rest) {
118
118
  const p = rest.slice(0, rest.length - 1), cb = rest[rest.length - 1];
@@ -870,6 +870,14 @@ var ConfigSchema = {
870
870
  uniqueItems: "Invalid config; duplicates in requestHeaders"
871
871
  }
872
872
  },
873
+ dedicatedProxyURL: {
874
+ type: "string",
875
+ errorMessage: "Invalid config; dedicatedProxyURL must be a string"
876
+ },
877
+ geolocation: {
878
+ type: "string",
879
+ errorMessage: "Invalid config; geolocation must be a string like 'lat,lon'"
880
+ },
873
881
  allowDuplicateSnapshotNames: {
874
882
  type: "boolean",
875
883
  errorMessage: "Invalid config; allowDuplicateSnapshotNames must be true/false"
@@ -946,6 +954,9 @@ var WebStaticConfigSchema = {
946
954
  execute: {
947
955
  type: "object",
948
956
  properties: {
957
+ beforeNavigation: {
958
+ type: "string"
959
+ },
949
960
  afterNavigation: {
950
961
  type: "string"
951
962
  },
@@ -1878,7 +1889,7 @@ function startPollingForTunnel(ctx, build_id, baseline, projectToken, buildName)
1878
1889
  function stopTunnelHelper(ctx) {
1879
1890
  return __async(this, null, function* () {
1880
1891
  ctx.log.debug("stop-tunnel:: Stopping the tunnel now");
1881
- const tunnelRunningStatus = yield tunnelInstance.isRunning();
1892
+ const tunnelRunningStatus = yield tunnelInstance == null ? void 0 : tunnelInstance.isRunning();
1882
1893
  ctx.log.debug("stop-tunnel:: Running status of tunnel before stopping ? " + tunnelRunningStatus);
1883
1894
  const status = yield tunnelInstance.stop();
1884
1895
  ctx.log.debug("stop-tunnel:: Tunnel is Stopped ? " + status);
@@ -2573,7 +2584,10 @@ var server_default = (ctx) => __async(void 0, null, function* () {
2573
2584
  lastExternalResponse = externalResponse;
2574
2585
  if (externalResponse.statusCode === 200) {
2575
2586
  replyCode = 200;
2576
- replyBody = externalResponse.data;
2587
+ replyBody = {
2588
+ data: externalResponse.data,
2589
+ error: externalResponse.error.message
2590
+ };
2577
2591
  return reply.code(replyCode).send(replyBody);
2578
2592
  } else if (externalResponse.statusCode === 202) {
2579
2593
  replyBody = externalResponse.data;
@@ -2585,22 +2599,15 @@ var server_default = (ctx) => __async(void 0, null, function* () {
2585
2599
  } else {
2586
2600
  ctx.log.debug(`Unexpected response from external API: ${JSON.stringify(externalResponse)}`);
2587
2601
  replyCode = 500;
2588
- replyBody = {
2589
- error: {
2590
- message: `Unexpected response from external API: ${externalResponse.statusCode}`,
2591
- externalApiStatus: externalResponse.statusCode
2592
- }
2593
- };
2594
- return reply.code(replyCode).send(replyBody);
2602
+ return reply.code(replyCode).send(externalResponse);
2595
2603
  }
2596
2604
  ctx.log.debug(`timeoutDuration: ${timeoutDuration}`);
2597
2605
  ctx.log.debug(`Time passed: ${Date.now() - startTime}`);
2598
2606
  if (Date.now() - startTime > timeoutDuration) {
2599
2607
  replyCode = 202;
2600
2608
  replyBody = {
2601
- data: {
2602
- message: "Request timed out-> Snapshot still processing"
2603
- }
2609
+ error: "Request timed out, Snapshot still processing",
2610
+ data: lastExternalResponse.data
2604
2611
  };
2605
2612
  return reply.code(replyCode).send(replyBody);
2606
2613
  }
@@ -2791,7 +2798,7 @@ var authExec_default = (ctx) => {
2791
2798
  };
2792
2799
 
2793
2800
  // package.json
2794
- var version = "4.1.41";
2801
+ var version = "4.1.42";
2795
2802
  var package_default = {
2796
2803
  name: "@lambdatest/smartui-cli",
2797
2804
  version,
@@ -2879,10 +2886,15 @@ var httpClient = class {
2879
2886
  }
2880
2887
  const axiosConfig = {
2881
2888
  baseURL: SMARTUI_CLIENT_API_URL,
2882
- proxy: proxyUrl ? {
2889
+ proxy: proxyUrl ? __spreadValues({
2883
2890
  host: proxyUrl.hostname,
2884
2891
  port: proxyUrl.port ? Number(proxyUrl.port) : 80
2885
- } : false
2892
+ }, proxyUrl.username && proxyUrl.password ? {
2893
+ auth: {
2894
+ username: proxyUrl.username,
2895
+ password: proxyUrl.password
2896
+ }
2897
+ } : {}) : false
2886
2898
  };
2887
2899
  if (SMARTUI_API_SKIP_CERTIFICATES) {
2888
2900
  axiosConfig.httpsAgent = new https__namespace.default.Agent({
@@ -2987,12 +2999,20 @@ var httpClient = class {
2987
2999
  }
2988
3000
  }, log2);
2989
3001
  if (response && response.projectToken) {
3002
+ let orgId = 0;
3003
+ let userId = 0;
2990
3004
  this.projectToken = response.projectToken;
2991
3005
  env.PROJECT_TOKEN = response.projectToken;
2992
3006
  if (response.message && response.message.includes("Project created successfully")) {
2993
3007
  result = 2;
2994
3008
  }
2995
- return result;
3009
+ if (response.orgId) {
3010
+ orgId = response.orgId;
3011
+ }
3012
+ if (response.userId) {
3013
+ userId = response.userId;
3014
+ }
3015
+ return { authResult: result, orgId, userId };
2996
3016
  } else {
2997
3017
  throw new Error("Authentication failed, project token not received");
2998
3018
  }
@@ -3483,6 +3503,20 @@ var httpClient = class {
3483
3503
  }
3484
3504
  }, ctx.log);
3485
3505
  }
3506
+ getGeolocationProxy(geoLocation, log2) {
3507
+ return __async(this, null, function* () {
3508
+ try {
3509
+ const resp = yield this.request({
3510
+ url: "/geolocation",
3511
+ method: "GET",
3512
+ params: { geoLocation }
3513
+ }, log2);
3514
+ return resp;
3515
+ } catch (error) {
3516
+ this.handleHttpError(error, log2);
3517
+ }
3518
+ });
3519
+ }
3486
3520
  uploadPdf(ctx, form, buildName) {
3487
3521
  return __async(this, null, function* () {
3488
3522
  form.append("projectToken", this.projectToken);
@@ -3682,6 +3716,8 @@ var ctx_default = (options) => {
3682
3716
  ignoreHTTPSErrors: (_i = config.ignoreHTTPSErrors) != null ? _i : false,
3683
3717
  skipBuildCreation: (_j = config.skipBuildCreation) != null ? _j : false,
3684
3718
  tunnel: tunnelObj,
3719
+ dedicatedProxyURL: config.dedicatedProxyURL || "",
3720
+ geolocation: config.geolocation || "",
3685
3721
  userAgent: config.userAgent || "",
3686
3722
  requestHeaders: config.requestHeaders || {},
3687
3723
  allowDuplicateSnapshotNames,
@@ -5746,7 +5782,7 @@ var auth_default = (ctx) => {
5746
5782
  task: (ctx2, task) => __async(void 0, null, function* () {
5747
5783
  updateLogContext({ task: "auth" });
5748
5784
  try {
5749
- const authResult = yield ctx2.client.auth(ctx2.log, ctx2.env);
5785
+ const { authResult, orgId, userId } = yield ctx2.client.auth(ctx2.log, ctx2.env);
5750
5786
  if (authResult === 2) {
5751
5787
  task.output = chalk__default.default.gray(`New project '${ctx2.env.PROJECT_NAME}' created successfully`);
5752
5788
  } else if (authResult === 0) {
@@ -5754,6 +5790,8 @@ var auth_default = (ctx) => {
5754
5790
  } else if (authResult === 1) {
5755
5791
  task.output = chalk__default.default.gray(`Using existing project '${ctx2.env.PROJECT_NAME}'`);
5756
5792
  }
5793
+ ctx2.orgId = orgId;
5794
+ ctx2.userId = userId;
5757
5795
  task.title = "Authenticated with SmartUI";
5758
5796
  } catch (error) {
5759
5797
  ctx2.log.debug(error);
@@ -5803,6 +5841,7 @@ function captureScreenshotsForConfig(ctx, browsers, urlConfig, browserName, rend
5803
5841
  return __async(this, null, function* () {
5804
5842
  ctx.log.debug(`*** urlConfig ${JSON.stringify(urlConfig)}`);
5805
5843
  let { name, url, waitForTimeout, execute, pageEvent, userAgent } = urlConfig;
5844
+ let beforeNavigationScript = execute == null ? void 0 : execute.beforeNavigation;
5806
5845
  let afterNavigationScript = execute == null ? void 0 : execute.afterNavigation;
5807
5846
  let beforeSnapshotScript = execute == null ? void 0 : execute.beforeSnapshot;
5808
5847
  let waitUntilEvent = pageEvent || process.env.SMARTUI_PAGE_WAIT_UNTIL_EVENT || "load";
@@ -5813,6 +5852,69 @@ function captureScreenshotsForConfig(ctx, browsers, urlConfig, browserName, rend
5813
5852
  let contextOptions = {
5814
5853
  ignoreHTTPSErrors: ctx.config.ignoreHTTPSErrors
5815
5854
  };
5855
+ try {
5856
+ if (ctx.config.tunnel && ctx.config.tunnel.tunnelName) {
5857
+ if (ctx.tunnelDetails && ctx.tunnelDetails.tunnelPort != -1 && ctx.tunnelDetails.tunnelHost) {
5858
+ const tunnelServer = `http://${ctx.tunnelDetails.tunnelHost}:${ctx.tunnelDetails.tunnelPort}`;
5859
+ ctx.log.info(`URL Capture :: Using tunnel address: ${tunnelServer}`);
5860
+ contextOptions.proxy = { server: tunnelServer };
5861
+ } else {
5862
+ let tunnelResp = yield ctx.client.getTunnelDetails(ctx, ctx.log);
5863
+ ctx.log.debug(`Tunnel Response: ${JSON.stringify(tunnelResp)}`);
5864
+ if (tunnelResp && tunnelResp.data && tunnelResp.data.host && tunnelResp.data.port) {
5865
+ ctx.tunnelDetails = {
5866
+ tunnelHost: tunnelResp.data.host,
5867
+ tunnelPort: tunnelResp.data.port,
5868
+ tunnelName: tunnelResp.data.tunnel_name
5869
+ };
5870
+ const tunnelServer = `http://${ctx.tunnelDetails.tunnelHost}:${ctx.tunnelDetails.tunnelPort}`;
5871
+ ctx.log.info(`URL Capture :: Using tunnel address: ${tunnelServer}`);
5872
+ contextOptions.proxy = { server: tunnelServer };
5873
+ } else if (tunnelResp && tunnelResp.error) {
5874
+ if (tunnelResp.error.message) {
5875
+ ctx.log.warn(`Error while fetching tunnel details: ${tunnelResp.error.message}`);
5876
+ }
5877
+ }
5878
+ }
5879
+ } else if (ctx.config.geolocation && ctx.config.geolocation !== "") {
5880
+ if (ctx.geolocationData && ctx.geolocationData.proxy && ctx.geolocationData.username && ctx.geolocationData.password && ctx.geolocationData.geoCode === ctx.config.geolocation) {
5881
+ ctx.log.info(`URL Capture :: Using cached geolocation proxy for ${ctx.config.geolocation}`);
5882
+ contextOptions.proxy = {
5883
+ server: ctx.geolocationData.proxy,
5884
+ username: ctx.geolocationData.username,
5885
+ password: ctx.geolocationData.password
5886
+ };
5887
+ } else {
5888
+ const geoResp = yield ctx.client.getGeolocationProxy(ctx.config.geolocation, ctx.log);
5889
+ ctx.log.debug(`Geolocation proxy response: ${JSON.stringify(geoResp)}`);
5890
+ if (geoResp && geoResp.data && geoResp.data.proxy && geoResp.data.username && geoResp.data.password) {
5891
+ ctx.log.info(`URL Capture :: Using geolocation proxy for ${ctx.config.geolocation}`);
5892
+ ctx.geolocationData = {
5893
+ proxy: geoResp.data.proxy,
5894
+ username: geoResp.data.username,
5895
+ password: geoResp.data.password,
5896
+ geoCode: ctx.config.geolocation
5897
+ };
5898
+ contextOptions.proxy = {
5899
+ server: geoResp.data.proxy,
5900
+ username: geoResp.data.username,
5901
+ password: geoResp.data.password
5902
+ };
5903
+ } else {
5904
+ ctx.log.warn(`Geolocation proxy not available for '${ctx.config.geolocation}', falling back if dedicatedProxyURL present`);
5905
+ if (ctx.config.dedicatedProxyURL && ctx.config.dedicatedProxyURL !== "") {
5906
+ ctx.log.info(`URL Capture :: Using dedicated proxy: ${ctx.config.dedicatedProxyURL}`);
5907
+ contextOptions.proxy = { server: ctx.config.dedicatedProxyURL };
5908
+ }
5909
+ }
5910
+ }
5911
+ } else if (ctx.config.dedicatedProxyURL && ctx.config.dedicatedProxyURL !== "") {
5912
+ ctx.log.info(`URL Capture :: Using dedicated proxy: ${ctx.config.dedicatedProxyURL}`);
5913
+ contextOptions.proxy = { server: ctx.config.dedicatedProxyURL };
5914
+ }
5915
+ } catch (e) {
5916
+ ctx.log.debug(`Failed resolving tunnel/proxy details: ${e}`);
5917
+ }
5816
5918
  let page;
5817
5919
  if (browserName == constants_default.CHROME)
5818
5920
  contextOptions.userAgent = constants_default.CHROME_USER_AGENT;
@@ -5834,6 +5936,15 @@ function captureScreenshotsForConfig(ctx, browsers, urlConfig, browserName, rend
5834
5936
  const browser = browsers[browserName];
5835
5937
  context = yield browser == null ? void 0 : browser.newContext(contextOptions);
5836
5938
  page = yield context == null ? void 0 : context.newPage();
5939
+ if (beforeNavigationScript && beforeNavigationScript !== "") {
5940
+ const wrappedScript = new Function("page", `
5941
+ return (async () => {
5942
+ ${beforeNavigationScript}
5943
+ })();
5944
+ `);
5945
+ ctx.log.debug(`Executing before navigation script: ${wrappedScript}`);
5946
+ yield wrappedScript(page);
5947
+ }
5837
5948
  const headersObject = {};
5838
5949
  if (ctx.config.requestHeaders && Array.isArray(ctx.config.requestHeaders)) {
5839
5950
  ctx.config.requestHeaders.forEach((headerObj) => {
@@ -5849,6 +5960,11 @@ function captureScreenshotsForConfig(ctx, browsers, urlConfig, browserName, rend
5849
5960
  });
5850
5961
  });
5851
5962
  }
5963
+ if (ctx.config.basicAuthorization) {
5964
+ ctx.log.debug(`Adding basic authorization to the headers for root url`);
5965
+ let token = Buffer.from(`${ctx.config.basicAuthorization.username}:${ctx.config.basicAuthorization.password}`).toString("base64");
5966
+ headersObject["Authorization"] = `Basic ${token}`;
5967
+ }
5852
5968
  ctx.log.debug(`Combined headers: ${JSON.stringify(headersObject)}`);
5853
5969
  if (Object.keys(headersObject).length > 0) {
5854
5970
  yield page.setExtraHTTPHeaders(headersObject);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lambdatest/smartui-cli",
3
- "version": "4.1.41",
3
+ "version": "4.1.42",
4
4
  "description": "A command line interface (CLI) to run SmartUI tests on LambdaTest",
5
5
  "files": [
6
6
  "dist/**/*"