@datacamp/learn-vm-scripts 1.8.8 → 1.10.0
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.
- package/dist/index.cjs +83 -27
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -366649,13 +366649,47 @@ var setFullscreen = async (page, provider) => {
|
|
|
366649
366649
|
log(`Failed to set fullscreen for ${provider}: ${error}`);
|
|
366650
366650
|
}
|
|
366651
366651
|
};
|
|
366652
|
+
var waitForStableBox = async (page, selector, stableMs = 200) => {
|
|
366653
|
+
await page.waitForSelector(selector, { visible: true });
|
|
366654
|
+
return page.waitForFunction(
|
|
366655
|
+
(sel, stable) => {
|
|
366656
|
+
const el = document.querySelector(sel);
|
|
366657
|
+
if (!el) return false;
|
|
366658
|
+
const now = performance.now();
|
|
366659
|
+
const rect = el.getBoundingClientRect();
|
|
366660
|
+
if (!window.__stableBox) {
|
|
366661
|
+
window.__stableBox = {};
|
|
366662
|
+
}
|
|
366663
|
+
const previous = window.__stableBox[sel];
|
|
366664
|
+
if (!previous) {
|
|
366665
|
+
window.__stableBox[sel] = { rect, t: now };
|
|
366666
|
+
return false;
|
|
366667
|
+
}
|
|
366668
|
+
const samePos = Math.abs(previous.rect.x - rect.x) < 0.5 && Math.abs(previous.rect.y - rect.y) < 0.5 && Math.abs(previous.rect.width - rect.width) < 0.5 && Math.abs(previous.rect.height - rect.height) < 0.5;
|
|
366669
|
+
if (!samePos) {
|
|
366670
|
+
window.__stableBox[sel] = { rect, t: now };
|
|
366671
|
+
return false;
|
|
366672
|
+
}
|
|
366673
|
+
return now - previous.t >= stable;
|
|
366674
|
+
},
|
|
366675
|
+
{ timeout: 3e3 },
|
|
366676
|
+
selector,
|
|
366677
|
+
stableMs
|
|
366678
|
+
);
|
|
366679
|
+
};
|
|
366652
366680
|
|
|
366653
366681
|
// src/setInput.ts
|
|
366654
|
-
var setInput = ({
|
|
366682
|
+
var setInput = async ({
|
|
366655
366683
|
page,
|
|
366656
366684
|
querySelector,
|
|
366657
366685
|
value
|
|
366658
366686
|
}) => {
|
|
366687
|
+
try {
|
|
366688
|
+
await waitForStableBox(page, querySelector);
|
|
366689
|
+
} catch (error) {
|
|
366690
|
+
log(`Error waiting for stable box: ${error}`);
|
|
366691
|
+
}
|
|
366692
|
+
await page.type(querySelector, value);
|
|
366659
366693
|
return page.evaluate(
|
|
366660
366694
|
({ querySelector: querySelector2, value: value2 }) => {
|
|
366661
366695
|
document.querySelector(querySelector2).value = value2;
|
|
@@ -366697,11 +366731,9 @@ async function loginToAzure({
|
|
|
366697
366731
|
log("Navigating to Azure login page...");
|
|
366698
366732
|
await Promise.all([page.waitForNavigation(), page.goto(ensureHttps(url))]);
|
|
366699
366733
|
log("Entering email...");
|
|
366700
|
-
const usernameQuerySelector = '[name="loginfmt"]';
|
|
366701
|
-
await page.waitForSelector(usernameQuerySelector);
|
|
366702
366734
|
await setInput({
|
|
366703
366735
|
page,
|
|
366704
|
-
querySelector:
|
|
366736
|
+
querySelector: '[name="loginfmt"]',
|
|
366705
366737
|
value: username
|
|
366706
366738
|
});
|
|
366707
366739
|
await Promise.all([
|
|
@@ -366710,11 +366742,9 @@ async function loginToAzure({
|
|
|
366710
366742
|
]);
|
|
366711
366743
|
log("Email entered successfully");
|
|
366712
366744
|
log("Entering password...");
|
|
366713
|
-
const passwordQuerySelector = 'input[type="password"]';
|
|
366714
|
-
await page.waitForSelector(passwordQuerySelector, { visible: true });
|
|
366715
366745
|
await setInput({
|
|
366716
366746
|
page,
|
|
366717
|
-
querySelector:
|
|
366747
|
+
querySelector: 'input[type="password"]',
|
|
366718
366748
|
value: password
|
|
366719
366749
|
});
|
|
366720
366750
|
await Promise.all([
|
|
@@ -366751,15 +366781,11 @@ async function loginToAWS({
|
|
|
366751
366781
|
}) {
|
|
366752
366782
|
log("Navigating to AWS login page...");
|
|
366753
366783
|
await page.goto(ensureHttps(url));
|
|
366754
|
-
await page.waitForSelector('input[name="username"]');
|
|
366755
|
-
await page.type('input[name="username"]', username);
|
|
366756
366784
|
await setInput({
|
|
366757
366785
|
page,
|
|
366758
366786
|
querySelector: 'input[name="username"]',
|
|
366759
366787
|
value: username
|
|
366760
366788
|
});
|
|
366761
|
-
await page.waitForSelector('input[name="password"]');
|
|
366762
|
-
await page.type('input[name="password"]', password);
|
|
366763
366789
|
await setInput({
|
|
366764
366790
|
page,
|
|
366765
366791
|
querySelector: 'input[name="password"]',
|
|
@@ -366835,30 +366861,34 @@ var resetChrome = async ({ userDataDir }) => {
|
|
|
366835
366861
|
};
|
|
366836
366862
|
|
|
366837
366863
|
// src/snowflakeLogin.ts
|
|
366864
|
+
var USERNAME_SELECTOR = 'input[autocomplete="username"]';
|
|
366865
|
+
var PASSWORD_SELECTOR = 'input[autocomplete="current-password"]';
|
|
366866
|
+
var OTP_SELECTOR = 'input[autocomplete="one-time-code"]';
|
|
366838
366867
|
async function loginToSnowflake({
|
|
366839
366868
|
url,
|
|
366840
366869
|
username,
|
|
366841
366870
|
page,
|
|
366842
|
-
password
|
|
366871
|
+
password,
|
|
366872
|
+
otp
|
|
366843
366873
|
}) {
|
|
366844
366874
|
log("Navigating to Snowflake login page...");
|
|
366845
366875
|
await page.goto(ensureHttps(url));
|
|
366846
|
-
await page.waitForSelector(
|
|
366847
|
-
const usernameField = await page.$(
|
|
366876
|
+
await page.waitForSelector(USERNAME_SELECTOR);
|
|
366877
|
+
const usernameField = await page.$(USERNAME_SELECTOR);
|
|
366848
366878
|
if (!usernameField) {
|
|
366849
366879
|
throw new Error("Username field not found");
|
|
366850
366880
|
}
|
|
366851
366881
|
await usernameField.click({ clickCount: 3 });
|
|
366852
366882
|
await page.keyboard.press("Backspace");
|
|
366853
|
-
await page.type(
|
|
366854
|
-
await page.waitForSelector(
|
|
366855
|
-
const passwordField = await page.$(
|
|
366883
|
+
await page.type(USERNAME_SELECTOR, username);
|
|
366884
|
+
await page.waitForSelector(PASSWORD_SELECTOR);
|
|
366885
|
+
const passwordField = await page.$(PASSWORD_SELECTOR);
|
|
366856
366886
|
if (!passwordField) {
|
|
366857
366887
|
throw new Error("Password field not found");
|
|
366858
366888
|
}
|
|
366859
366889
|
await passwordField.click({ clickCount: 3 });
|
|
366860
366890
|
await page.keyboard.press("Backspace");
|
|
366861
|
-
await page.type(
|
|
366891
|
+
await page.type(PASSWORD_SELECTOR, password);
|
|
366862
366892
|
await page.waitForSelector("button:not([disabled])");
|
|
366863
366893
|
const buttons = await page.$$("button:not([disabled])");
|
|
366864
366894
|
let signInButtonHandle;
|
|
@@ -366876,7 +366906,37 @@ async function loginToSnowflake({
|
|
|
366876
366906
|
throw new Error("Could not find an enabled Sign in button on the page.");
|
|
366877
366907
|
}
|
|
366878
366908
|
await signInButtonHandle.click();
|
|
366879
|
-
|
|
366909
|
+
if (otp != null) {
|
|
366910
|
+
log("Handling Snowflake OTP challenge...");
|
|
366911
|
+
await page.waitForSelector(OTP_SELECTOR, {
|
|
366912
|
+
timeout: 15e3
|
|
366913
|
+
});
|
|
366914
|
+
const otpField = await page.$(OTP_SELECTOR);
|
|
366915
|
+
if (!otpField) {
|
|
366916
|
+
throw new Error("OTP field not found");
|
|
366917
|
+
}
|
|
366918
|
+
await otpField.click({ clickCount: 3 });
|
|
366919
|
+
await page.keyboard.press("Backspace");
|
|
366920
|
+
await page.type(OTP_SELECTOR, otp);
|
|
366921
|
+
const enabledButtons = await page.$$("button:not([disabled])");
|
|
366922
|
+
let continueButtonHandle;
|
|
366923
|
+
for (const btn of enabledButtons) {
|
|
366924
|
+
const textContent = await page.evaluate(
|
|
366925
|
+
(el) => el.textContent?.trim(),
|
|
366926
|
+
btn
|
|
366927
|
+
);
|
|
366928
|
+
if (textContent === "Continue") {
|
|
366929
|
+
continueButtonHandle = btn;
|
|
366930
|
+
break;
|
|
366931
|
+
}
|
|
366932
|
+
}
|
|
366933
|
+
if (!continueButtonHandle) {
|
|
366934
|
+
throw new Error("Could not find an enabled Continue button on the page.");
|
|
366935
|
+
}
|
|
366936
|
+
await continueButtonHandle.click();
|
|
366937
|
+
log("Snowflake OTP challenge completed");
|
|
366938
|
+
}
|
|
366939
|
+
log("Logged in to Snowflake");
|
|
366880
366940
|
}
|
|
366881
366941
|
|
|
366882
366942
|
// src/fabricLogin.ts
|
|
@@ -366889,7 +366949,6 @@ async function loginToFabric({
|
|
|
366889
366949
|
log("Navigating to Fabric login page...");
|
|
366890
366950
|
await page.goto(ensureHttps(url));
|
|
366891
366951
|
log("Entering email...");
|
|
366892
|
-
await page.waitForSelector('input[id="email"]');
|
|
366893
366952
|
await setInput({
|
|
366894
366953
|
page,
|
|
366895
366954
|
querySelector: 'input[id="email"]',
|
|
@@ -366902,7 +366961,6 @@ async function loginToFabric({
|
|
|
366902
366961
|
maxRetries: 10
|
|
366903
366962
|
});
|
|
366904
366963
|
log("Entering password...");
|
|
366905
|
-
await page.waitForSelector('input[type="password"]');
|
|
366906
366964
|
await setInput({
|
|
366907
366965
|
page,
|
|
366908
366966
|
querySelector: 'input[type="password"]',
|
|
@@ -366960,15 +367018,11 @@ async function loginToN8N({
|
|
|
366960
367018
|
}) {
|
|
366961
367019
|
log("Navigating to N8N login page...");
|
|
366962
367020
|
await page.goto(ensureHttps(url));
|
|
366963
|
-
await page.waitForSelector(usernameInputSelector);
|
|
366964
|
-
await page.type(usernameInputSelector, username);
|
|
366965
367021
|
await setInput({
|
|
366966
367022
|
page,
|
|
366967
367023
|
querySelector: usernameInputSelector,
|
|
366968
367024
|
value: username
|
|
366969
367025
|
});
|
|
366970
|
-
await page.waitForSelector(passwordInputSelector);
|
|
366971
|
-
await page.type(passwordInputSelector, password);
|
|
366972
367026
|
await setInput({
|
|
366973
367027
|
page,
|
|
366974
367028
|
querySelector: passwordInputSelector,
|
|
@@ -366989,7 +367043,8 @@ var LoggedInProvidersSchema = objectType({
|
|
|
366989
367043
|
cloudProvider: enumType(["aws", "azure", "snowflake", "n8n"]),
|
|
366990
367044
|
username: stringType(),
|
|
366991
367045
|
password: stringType(),
|
|
366992
|
-
url: stringType()
|
|
367046
|
+
url: stringType(),
|
|
367047
|
+
otp: stringType().min(1).optional()
|
|
366993
367048
|
});
|
|
366994
367049
|
var Input = discriminatedUnionType("cloudProvider", [
|
|
366995
367050
|
LoggedOutProvidersSchema,
|
|
@@ -367045,7 +367100,8 @@ var handleInput = async ({ line, page }) => {
|
|
|
367045
367100
|
url: input.url,
|
|
367046
367101
|
username: input.username,
|
|
367047
367102
|
page,
|
|
367048
|
-
password: input.password
|
|
367103
|
+
password: input.password,
|
|
367104
|
+
otp: input.otp
|
|
367049
367105
|
});
|
|
367050
367106
|
break;
|
|
367051
367107
|
case "perplexity":
|
package/package.json
CHANGED