Skip to content

Commit 9109dde

Browse files
committed
checkpoint automation changes
1 parent da20453 commit 9109dde

File tree

2 files changed

+96
-7
lines changed

2 files changed

+96
-7
lines changed

injected/src/features/autofill-password-import.js

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ export default class AutofillPasswordImport extends ContentFeature {
5252

5353
#domLoaded;
5454

55+
#currentLocation;
56+
57+
#isBookmarkModalVisible = false;
58+
#isBookmarkProcessed = false;
59+
5560
/** @type {WeakSet<Element>} */
5661
#tappedElements = new WeakSet();
5762

@@ -422,8 +427,12 @@ export default class AutofillPasswordImport extends ContentFeature {
422427
}
423428
}
424429

425-
handleBookmarkImportPath(pathname) {
430+
async handleBookmarkImportPath(pathname) {
426431
console.log('DEEP DEBUG autofill-password-import: handleBookmarkImportPath', pathname);
432+
if (pathname === '/' && !this.#isBookmarkModalVisible) {
433+
await this.clickDisselectAllButton();
434+
await this.selectBookmark();
435+
}
427436
}
428437

429438
/**
@@ -508,7 +517,87 @@ export default class AutofillPasswordImport extends ContentFeature {
508517
this.#settingsButtonSettings = this.getFeatureSetting('settingsButton');
509518
}
510519

520+
/** Bookmark import code */
521+
get disselectAllButtonSelector() {
522+
return 'c-wiz[data-node-index="4;0"] button';
523+
}
524+
525+
get bookmarkSelectButtonSelector() {
526+
return 'fieldset.rcetic input';
527+
}
528+
529+
get chromeSectionSelector() {
530+
return 'c-wiz [data-id="chrome"]';
531+
}
532+
533+
async findDisselectAllButton() {
534+
return await withExponentialBackoff(() => document.querySelectorAll(this.disselectAllButtonSelector)[1]);
535+
}
536+
async selectBookmark() {
537+
if (this.#isBookmarkProcessed) {
538+
return;
539+
}
540+
const chromeDataButtonSelector = `${this.chromeSectionSelector} button`;
541+
const chromeDataButton = /** @type HTMLButtonElement */ (
542+
await withExponentialBackoff(() => document.querySelectorAll(chromeDataButtonSelector)[1], 5)
543+
);
544+
if (chromeDataButton != null) {
545+
this.#isBookmarkModalVisible = true;
546+
chromeDataButton.focus();
547+
chromeDataButton.click();
548+
}
549+
await this.domLoaded;
550+
const disselectAllButton = /** @type HTMLButtonElement */ (
551+
await withExponentialBackoff(() => document.querySelectorAll('fieldset.rcetic button')[1])
552+
);
553+
if (disselectAllButton != null) {
554+
disselectAllButton.click();
555+
}
556+
557+
558+
const bookmarkSelectButton = /** @type HTMLInputElement */ (
559+
await withExponentialBackoff(() => document.querySelectorAll(this.bookmarkSelectButtonSelector)[1])
560+
);
561+
562+
await withExponentialBackoff(() => !bookmarkSelectButton?.checked);
563+
564+
if (bookmarkSelectButton != null) {
565+
bookmarkSelectButton.click();
566+
}
567+
568+
const okButton = /** @type HTMLButtonElement */ (document.querySelectorAll('div[role="button"]')[7]);
569+
570+
await withExponentialBackoff(() => okButton.ariaDisabled !== 'true');
571+
572+
if (okButton != null) {
573+
okButton.click();
574+
this.#isBookmarkModalVisible = false;
575+
this.#isBookmarkProcessed = true;
576+
}
577+
}
578+
579+
async clickDisselectAllButton() {
580+
const element = /** @type HTMLButtonElement */ (await this.findDisselectAllButton());
581+
console.log('Deep element', element);
582+
if (element != null) {
583+
element.click();
584+
}
585+
586+
const chromeSectionElement = /** @type HTMLInputElement */ (
587+
await withExponentialBackoff(() => document.querySelectorAll(this.chromeSectionSelector)[0].querySelector('input'))
588+
);
589+
console.log('DEEP chromeSectionElement', chromeSectionElement);
590+
591+
// First wait for the element to become unchecked (due to slow disselection)
592+
await withExponentialBackoff(() => !chromeSectionElement?.checked);
593+
594+
chromeSectionElement.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'center' });
595+
596+
chromeSectionElement?.click();
597+
}
598+
511599
urlChanged() {
600+
console.log('DEEP DEBUG autofill-password-import: urlChanged', window.location);
512601
this.handleLocation(window.location);
513602
}
514603

injected/src/utils.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -803,22 +803,22 @@ export function legacySendMessage(messageType, options) {
803803
}
804804

805805
/**
806-
* Takes a function that returns an element and tries to find it with exponential backoff.
806+
* Takes a function that returns an element and tries to execute it until it returns a valid result or the max attempts are reached.
807807
* @param {number} delay
808808
* @param {number} [maxAttempts=4] - The maximum number of attempts to find the element.
809809
* @param {number} [delay=500] - The initial delay to be used to create the exponential backoff.
810-
* @returns {Promise<Element|HTMLElement|null>}
810+
* @returns {Promise<any>}
811811
*/
812812
export function withExponentialBackoff(fn, maxAttempts = 4, delay = 500) {
813813
return new Promise((resolve, reject) => {
814814
let attempts = 0;
815815
const tryFn = () => {
816816
attempts += 1;
817-
const error = new Error('Element not found');
817+
const error = new Error('Result is invalid');
818818
try {
819-
const element = fn();
820-
if (element) {
821-
resolve(element);
819+
const result = fn();
820+
if (result) {
821+
resolve(result);
822822
} else if (attempts < maxAttempts) {
823823
setTimeout(tryFn, delay * Math.pow(2, attempts));
824824
} else {

0 commit comments

Comments
 (0)