From 0171a7ad60b6607c7ef49997894a192a8441260d Mon Sep 17 00:00:00 2001 From: alicechai Date: Mon, 12 Feb 2024 17:30:37 +0700 Subject: [PATCH] feat: download and unpack extension file --- .../typhon/convert-to-zip.py | 43 +++++ .../typhon/typhon-wallet-download.spec.ts | 4 +- .../typhon/typhon-wallet-logout.ts | 50 ------ .../typhon/typhon-wallet-registration.ts | 168 ------------------ 4 files changed, 45 insertions(+), 220 deletions(-) create mode 100644 tests/wallet-automation/typhon/convert-to-zip.py delete mode 100644 tests/wallet-automation/typhon/typhon-wallet-logout.ts delete mode 100644 tests/wallet-automation/typhon/typhon-wallet-registration.ts diff --git a/tests/wallet-automation/typhon/convert-to-zip.py b/tests/wallet-automation/typhon/convert-to-zip.py new file mode 100644 index 0000000000..2ffe3d7cd9 --- /dev/null +++ b/tests/wallet-automation/typhon/convert-to-zip.py @@ -0,0 +1,43 @@ +import os +import sys +import zipfile + +def crx_to_zip(crx_file_path, zip_file_path=None): + if not zip_file_path: + # If no zip file path is provided, use the same location and name as the crx file + zip_file_path = os.path.splitext(crx_file_path)[0] + '.zip' + + with open(crx_file_path, 'rb') as crx_file: + # Read the CRX file's header (first 16 bytes) + crx_header = crx_file.read(16) + + # The actual zip content starts after the header, so we can skip the header + zip_content = crx_file.read() + + # Save the zip content to a new zip file + with open(zip_file_path, 'wb') as zip_file: + zip_file.write(zip_content) + + print(f"converted CRX to ZIP: {zip_file_path}") + return zip_file_path + +def unzip_file(zip_path, extract_to=None): + if extract_to is None: + extract_to = os.path.dirname(zip_path) + + if not os.path.exists(extract_to): + os.makedirs(extract_to) + + with zipfile.ZipFile(zip_path, 'r') as zip_ref: + zip_ref.extractall(extract_to) + print(f"Extracted all files in {zip_path} to {extract_to}") + +# Combine the operations +if __name__ == "__main__": + if len(sys.argv) != 2: + print("Usage: python script.py ") + sys.exit(1) + + crx_path = sys.argv[1] + zip_path = crx_to_zip(crx_path) # Convert CRX to ZIP + unzip_file(zip_path) # Unzip the converted file diff --git a/tests/wallet-automation/typhon/typhon-wallet-download.spec.ts b/tests/wallet-automation/typhon/typhon-wallet-download.spec.ts index dc5db4ae69..a886eb621d 100644 --- a/tests/wallet-automation/typhon/typhon-wallet-download.spec.ts +++ b/tests/wallet-automation/typhon/typhon-wallet-download.spec.ts @@ -3,7 +3,7 @@ import * as fs from 'fs/promises'; import * as path from 'path'; const url = 'https://clients2.google.com/service/update2/crx?response=redirect&os=win&arch=x64&os_arch=x86_64&nacl_arch=x86-64&prod=chromiumcrx&prodchannel=beta&prodversion=79.0.3945.53&lang=ru&acceptformat=crx3&x=id%3Dkfdniefadaanbjodldohaedphafoffoh%26installsource%3Dondemand%26uc'; -const downloadPath = './downloads'; // Ensure this directory exists or add logic to create it +const downloadPath = path.resolve(__dirname, 'extensions'); // Ensure this directory exists or add logic to create it test('downloadFile test', async ({ page }) => { // Ensure the download directory exists @@ -25,7 +25,7 @@ test('downloadFile test', async ({ page }) => { timeout: 10000 }); } catch (error) { - console.log('Navigation caused an exception, likely due to immediate download:', error); + console.log('Navigation caused an exception, likely due to immediate download:', 'directDownload'); } // Wait for the download to complete diff --git a/tests/wallet-automation/typhon/typhon-wallet-logout.ts b/tests/wallet-automation/typhon/typhon-wallet-logout.ts deleted file mode 100644 index e716232514..0000000000 --- a/tests/wallet-automation/typhon/typhon-wallet-logout.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { test, chromium, Browser, Page } from '@playwright/test'; -import { getWalletCredentials } from './credentials'; -import { getSeedPhrase } from './seed-phrase'; - -test('Logout', async ({ }) => { - const path = require('path'); - const extensionPath: string = path.resolve(__dirname, 'extensions'); - // const extensionId: string = 'kfdniefadaanbjodldohaedphafoffoh'; // Replace with your extension's ID - // const extensionPage: string = 'tab.html'; // Replace with the specific page - const userDataDir = path.resolve(__dirname, 'usrdatadir'); - - const browser = await chromium.launchPersistentContext(userDataDir, { - headless: false, // extensions only work in headful mode =) - args: [ - `--disable-extensions-except=${extensionPath}`, - `--load-extension=${extensionPath}`, - ], - }); - - const page = await browser.newPage(); - await page.waitForTimeout(1000); // Adjust the timeout as needed - - // Get all pages (tabs) in the contextg - const pages = browser.pages(); - - // The new tab is typically the last one in the list - const newTab = pages[pages.length - 1]; - await newTab.bringToFront(); // Brings the new tab to the foreground - - const logOut = '//*[@id="app"]/div/div/div[3]/div/div/div[1]/div/div/div[2]/div[11]/div[2]'; - await newTab.waitForSelector(logOut, { state: 'visible' }); - await newTab.click(logOut); - - const chooseAccount = '//*[@id="app"]/div/div/div[3]/div/div[2]/div/div/div[2]/div'; - await newTab.waitForSelector(chooseAccount, { state: 'visible' }); - await newTab.click(chooseAccount); - - const removeAccount = '//*[@id="app"]/div/div/div[3]/div/div[2]/div/div/div[2]/div[4]/button'; - await newTab.waitForSelector(removeAccount, { state: 'visible' }); - await newTab.click(removeAccount); - - const confirmRemove = 'button.btn.bg-primary'; - await newTab.waitForSelector(confirmRemove, {state: 'visible'}); - await newTab.click(confirmRemove) - - const addNew = '//*[@id="app"]/div/div/div[3]/div/div[2]/div/div/div[4]'; - await newTab.waitForSelector(addNew, { state: 'visible' }); - await newTab.click(addNew); - -}); diff --git a/tests/wallet-automation/typhon/typhon-wallet-registration.ts b/tests/wallet-automation/typhon/typhon-wallet-registration.ts deleted file mode 100644 index 6fbec3f7f3..0000000000 --- a/tests/wallet-automation/typhon/typhon-wallet-registration.ts +++ /dev/null @@ -1,168 +0,0 @@ -import { test, chromium } from '@playwright/test'; -import { getWalletCredentials } from './credentials'; -import { getSeedPhrase } from './seed-phrase'; -const path = require('path'); - -test('import wallet', async ({ }) => { - const path = require('path'); - const extensionPath: string = path.resolve(__dirname, 'extensions'); - // const extensionId: string = 'kfdniefadaanbjodldohaedphafoffoh'; - // const extensionPage: string = 'tab.html'; - const userDataDir = path.resolve(__dirname, 'usrdatadir'); - - const browser = await chromium.launchPersistentContext(userDataDir, { - headless: false, // extensions only work in headful mode - args: [ - `--disable-extensions-except=${extensionPath}`, - `--load-extension=${extensionPath}`, - ], - }); - - const page = await browser.newPage(); - await page.waitForTimeout(1000); // adjust the timeout as needed - - const pages = browser.pages(); - - const newTab = pages[pages.length - 1]; - await newTab.bringToFront(); - - // interact with elements on the background page - const firstButtonSelector = '//*[@id="headlessui-menu-button-1"]'; - await newTab.waitForSelector(firstButtonSelector, { state: 'visible' }); - await newTab.click(firstButtonSelector); - - const secondButtonSelector = '#headlessui-menu-item-6'; - await newTab.waitForSelector(secondButtonSelector, { state: 'visible' }); - await newTab.click(secondButtonSelector); - - const thirdButtonSelector = '//*[text()="Import"]'; - await newTab.waitForSelector(thirdButtonSelector, { state: 'visible' }); - await newTab.click(thirdButtonSelector); - - const WalletCredentials = getWalletCredentials('WALLET1'); - const usernameInput = '#app > div > div > div.flex-grow.overflow-auto > div > div.my-5.flex.justify-center.py-16 > div > div > div > div:nth-child(2) > div > input'; - const passwordInput = '#app > div > div > div.flex-grow.overflow-auto > div > div.my-5.flex.justify-center.py-16 > div > div > div > div:nth-child(2) > div > div:nth-child(2) > input'; - const cfpwInput = '#app > div > div > div.flex-grow.overflow-auto > div > div.my-5.flex.justify-center.py-16 > div > div > div > div:nth-child(2) > div > div:nth-child(3) > input'; - await newTab.waitForSelector(usernameInput, { state: 'visible' }); - await newTab.waitForSelector(passwordInput, { state: 'visible' }); - await newTab.waitForSelector(cfpwInput, { state: 'visible' }); - await newTab.fill(usernameInput, WalletCredentials.username); - await newTab.fill(passwordInput, WalletCredentials.password); - await newTab.fill(cfpwInput, WalletCredentials.password); - - const agreeToTC = '#termsAndConditions' - await newTab.waitForSelector(agreeToTC, { state: 'visible' }); - await newTab.click(agreeToTC); - - const continueButton = '#app > div > div > div.flex-grow.overflow-auto > div > div.my-5.flex.justify-center.py-16 > div > div > div > div:nth-child(2) > div > button'; - await newTab.waitForSelector(continueButton, { state: 'visible' }); - await newTab.click(continueButton); - - async function clickBlankSpace(newTab) { - const blankSpace = '#app > div > div > div.flex-grow.overflow-auto > div > div.my-5.flex.justify-center.py-16 > div > div > div > div:nth-child(1) > div.flex.justify-between.items-start > div.flex-initial.flex.flex-col.mr-2 > span.text-primary.font-medium.text-xl'; - await newTab.waitForSelector(blankSpace, { state: 'visible' }); - await newTab.click(blankSpace); - } - - const seedPhrase = getSeedPhrase(); - - for (let i = 0; i < seedPhrase.length; i++) { - const ftSeedPhraseSelector = `#app > div > div > div.flex-grow.overflow-auto > div > div.my-5.flex.justify-center.py-16 > div > div > div > div:nth-child(1) > div:nth-child(2) > div > div > div > div > div:nth-child(${i + 1}) > div > input`; - await newTab.waitForSelector(ftSeedPhraseSelector, { state: 'visible' }); - await newTab.fill(ftSeedPhraseSelector, seedPhrase[i]); - } - - const unlockWallet = '#app > div > div > div.flex-grow.overflow-auto > div > div.my-5.flex.justify-center.py-16 > div > div > div > div.mt-6.text-center.flex.justify-center > button'; - await clickBlankSpace(newTab); - await newTab.waitForSelector(unlockWallet, { state: 'visible' }); - await newTab.click(unlockWallet); - - const divSelector = '//*[@id="lc"]/div[2]/div[1]/div[2]/div/div[1]/div[1]/div/div[2]/div[1]/div/span[1]'; - await newTab.waitForSelector(divSelector, { state: 'visible' }); - - // use the selector to retrieve the element handle - const elementHandle = await newTab.$(divSelector); - if (elementHandle) { - // retrieve the text content of the element - const textContent = await elementHandle.textContent(); - if (textContent !== null) { - // remove any formatting that might interfere with parseFloat - const cleanedText = textContent.replace(/,/g, '').trim(); - const floatValue = parseFloat(cleanedText); - console.log('ADA:', floatValue) - if (!isNaN(floatValue)) { - if (floatValue < 500) { - console.log('not eligible for voting ☹️'); - } else { - console.log('eligible for voting ☺'); - } - } else { - console.log('text content is not a valid float:', textContent); - } - } else { - console.log('no text content found for the specified selector:', divSelector); - } - } else { - console.log('element not found for the specified XPath:', divSelector); - } - - const logOut = '//*[@id="app"]/div/div/div[3]/div/div/div[1]/div/div/div[2]/div[11]/div[2]'; - await newTab.waitForSelector(logOut, { state: 'visible' }); - await newTab.click(logOut); - - const chooseAccount = '//*[@id="app"]/div/div/div[3]/div/div[2]/div/div/div[2]/div'; - await newTab.waitForSelector(chooseAccount, { state: 'visible' }); - await newTab.click(chooseAccount); - - const removeAccount = '//*[@id="app"]/div/div/div[3]/div/div[2]/div/div/div[2]/div[4]/button'; - await newTab.waitForSelector(removeAccount, { state: 'visible' }); - await newTab.click(removeAccount); - - const confirmRemove = 'button.btn.bg-primary'; - await newTab.waitForSelector(confirmRemove, { state: 'visible' }); - await newTab.click(confirmRemove) - - const addNew = '//*[@id="app"]/div/div/div[3]/div/div[2]/div/div/div[4]'; - await newTab.waitForSelector(addNew, { state: 'visible' }); - await newTab.click(addNew); - - // Keeping the browser open for debugging and verifying (remove the timeout or adjust as needed) - await page.waitForTimeout(300000); // Adjust the time as needed - await new Promise(resolve => { /* never resolves */ }); - -}); - -// const copyAddress = '#receiveAddress > div > div.grow > button'; -// await newTab.waitForSelector(copyAddress, { state: 'visible' }); -// await newTab.click(copyAddress); -// await newTab.waitForTimeout(500); -// const copiedText = await newTab.evaluate(() => navigator.clipboard.readText()); -// console.log('Copied Address:', copiedText); - -// const newTab2 = await browser.newPage(); -// await newTab2.goto('https://docs.cardano.org/cardano-testnet/tools/faucet/'); - -// async function clickBlankSpace2(newTab) { -// const blankSpace2 = '#gatsby-focus-wrapper > div > div > div.css-14y15z9.eh2b2dx0 > div > main > div > div.pageWrap > div.titleWrapper.css-0.ejiqw051 > h1'; -// await newTab.waitForSelector(blankSpace2, { state: 'visible' }); -// await newTab.click(blankSpace2); -// } - -// await clickBlankSpace2(newTab2); -// await newTab2.evaluate(() => window.scrollBy(0, window.innerHeight+100)); -// await newTab2.waitForTimeout(100); - -// const addressField = ('//*[@id="gatsby-focus-wrapper"]/div/div/div[2]/div/main/div/div[1]/div[2]/div/form/div[3]/div/div/input'); -// await newTab2.waitForSelector(addressField, { state: 'visible' }); -// await newTab2.click(addressField); -// await newTab2.keyboard.down('Meta'); // Use 'Meta' on Mac -// await newTab2.keyboard.press('V'); -// await newTab2.keyboard.up('Meta'); // Use 'Meta' on Mac - -// const captcha = '//*[@id="rc-anchor-container"]/div[3]/div[1]/div/div'; -// await newTab2.waitForSelector(captcha, { state: 'visible' }); -// await newTab2.click(captcha); - -// Keeping the browser open for debugging and verifying (remove the timeout or adjust as needed) -// await page.waitForTimeout(300000); // Adjust the time as needed -// await new Promise(resolve => { /* never resolves */ });