The exception thrown by Runtime.callFunctionOn was due to an error in LavaMoat - the property "Proxy" of globalThis is not accessible in scuttling mode

As I work on developing a Next.js app, I encountered some challenges when trying to run tests with selenium-webdriver. My webapp utilizes authentication with Metamask wallets, and the issue arises when attempting to import a wallet into a test window using selenium in order to log in on my webapp.

I've explored various approaches:

  • JavaScript tests that attempt to download or open a new chromewindow with Metamask installed
  • Python tests leveraging auto-metamask to import Metamask in a new window...

The setup I'm using is Ubuntu 22.04, Chrome version 113.0.5672.92, Chromedriver version 113.0.5672.63, Selenium-webdriver version 4.9.1, and Python3 version 3.10.6.

Here's the code snippet:

import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium import webdriver

def test_login_button():
    EXTENSION_PATH = '/nkbihfbeogaeaoehlefnkodbefgpgknn-10.30.1-www.Crx4Chrome.com.crx' 
    SECRET_RECOVERY_PHRASE = "my seed phrase"
    NEW_PASSWORD = "password"

    opt = webdriver.ChromeOptions()
    opt.add_extension(EXTENSION_PATH)
    
    driver = webdriver.Chrome(options=opt)
    time.sleep(3)

    driver.switch_to.window(driver.window_handles[1])
    time.sleep(3)

    wait = WebDriverWait(driver, 30)
    element = wait.until(EC.presence_of_element_located((By.XPATH, '//button[text()="Importar una cartera existente"]')))

    # Rest of the code

Encountered ERROR:

>       element = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[text()="Importar una cartera existente"]')))
...
E         at get (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/runtime-lavamoat.js:11200:17)
E         at serializationGuard (<anonymous>:198:67)
E         at buildError (<anonymous>:319:27)
E         (Session info: chrome=113.0.5672.92)`

I've consulted several resources:

My goal is to conduct tests that involve interacting with a Metamask wallet for logging into my application and subsequently engaging with smart contracts that handle functionality.

Answer №1

Crucial Update: As of May 15, 2023, this solution is operational and significant due to an issue that arose two years ago when the security implementation was not present in the MetaMask extension. It's worth noting that future changes may render this approach obsolete.

  • A developer from MetaMask contacted me and directed me to a link addressing the issue and its resolution. Check it out here: https://github.com/LavaMoat/LavaMoat/pull/360#issuecomment-1547726986

  • Key Points from the Discussion: LavaMoat serves as a sandbox for 'wrapping' JavaScript code to restrict access to certain APIs, thus mitigating potential security risks. Using an external webdriver triggers errors due to this restriction. The developers have consciously chosen this tradeoff to prioritize added security layers over API accessibility.

Solution

  • The developer suggested that I could create my customized version of MetaMask by disabling this particular security feature. Although this compromises some security measures, it suits my needs perfectly as I intend to apply it only in a development environment to test my Next.js app with selenium-webdriver.

Implementation Steps

  1. Visit the metamask-extension repository on GitHub and clone it to your local machine: https://github.com/MetaMask/metamask-extension. Review the README.md file for additional insights.
  2. In the cloned directory, navigate to the index.js file and update line 92 (
    scuttleGlobalThis: applyLavaMoat && shouldScuttle
    ) to scuttleGlobalThis: false.
  3. In the project's root folder, execute cp .metamaskcr.dist .metamaskcr.
  4. Edit the .metamaskcr file and adjust the following details:
    • INFURA_PROJECT_ID='replace with your infura project id'
      , consult , to obtain an Infura account if needed and create a suitable project at .
    • PASSWORD='replace with a password'
      ; for convenience and avoiding repeated entering.
    • SEGMENT_WRITE_KEY='replace with your segment write key'
      , reference , for setting up a Segment account and project.
  5. Following these adjustments, run yarn install and yarn dist from the project's root directory. This action will generate a /dist folder containing subfolders like /chrome, /firefox, and /sourcemaps. Ensure that the new EXTENSION_PATH specified in the Python code points to the /chrome folder in the project (or /firefox for Firefox users).
  • The final test code snippet would resemble the following:

    def test_login_button():
        EXTENSION_PATH = '/home/adrib/Universidad/4o/TFG/Proyecto/metamask-extension/dist/chrome'
    
        opt = Options()
        opt.add_argument(f'--load-extension={EXTENSION_PATH}')
    
        driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=opt)
        time.sleep(3)
        driver.switch_to.window(driver.window_handles[1])
        original_window = driver.current_window_handle
    
        time.sleep(3)
    
        time.sleep(3)
        WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.XPATH, "/html/body/div[1]/div/div[2]/div/div/div/ul/li[1]/div/input"))).click()
    
        WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[1]/div/div[2]/div/div/div/ul/li[3]/button"))).click()
    
        WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.XPATH, "//*[@id='app-content']/div/div[2]/div/div/div[2]/div/div[2]/div[1]/button"))).click()
    
        WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.XPATH, "//*[@id='app-content']/div/div[2]/div/div/div/div[5]/div[1]/footer/button[1]"))).click()
    

A big thank you to the prompt response and guidance provided by the MetaMask developer highlighted in the GitHub thread, @weizman.

Answer №2

Instead of relying on selenium to directly click a button using Python, you can use Python to execute a Javascript command that clicks the desired button. Below is a script that demonstrates how to click the "Submit" button:


# Finding and clicking the button with the text 'Submit' using Javascript
javascript = """
var buttons = document.getElementsByTagName('button');
for (var i = 0; i < buttons.length; i++) {
    if (buttons[i].textContent === 'Submit') {
        buttons[i].click();
        break;
    }
}
"""

# Executing the Javascript code
driver.execute_script(javascript)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What could be the reason for React not memoizing this callback?

I am encountering an issue with my Next.js project where the _app.tsx file contains the following code: const Root = ({ Component, pageProps }) => { ... const handleHistoryChange = useCallback((url) => { console.log({ url }); }, []); u ...

What is the best way to extract the value from an <input> element for utilization in an automated test with c#?

Can someone help me with extracting the "IMPORTANT STUFF" text from this HTML snippet? <input data-lock="2" data-val="true" data-val-required="Required" id="stuff" name="stuff" placeholder="blablabla" type="text" value="IMPORTANT STUFF" class=""> H ...

Encountering difficulty importing the global.css file into the root layout of Next.js 13

Hello everyone, I'm completely new to Next.js version 13. Recently, I started a project with Next.js 13 and have been exploring the new app directory. My current challenge is applying styles using Tailwind CSS. I've been following the instructi ...

What is the reason for Next.js and Gatsby.js necessitating the installation of Node.js, while React.js does not have that requirement?

Have you ever thought about the connection between Next.js and Gatsby.js, both being built on React.js? Could it be that the development environments are Node applications themselves? Or maybe there's something else I'm not seeing? While I have ...

Exploring Ways to Access Console.log() from Client Pages in Next.js

Struggling to debug my client-side renderings using `Console.log()` (Any tips on an easier way to use the debug tool would be appreciated), as I can only access server-rendered console logs. I'm attempting to track the flow of information for this ha ...

Error encountered while retrieving information from Excel spreadsheet resulting in a NullpointerException

I keep encountering a NullPointerException while trying to read data from an excel sheet at cell index = 6. I added a while loop with while(value != null) to handle null values, but the exception persists without any output being generated. I have attach ...

Python scraping causing webpage to fail loading

In my dataset, I have the URLs of Just Dial websites from which I am trying to extract specific information like seller names. Attached below is a sample data: dict_test = {"Id" : [1000, 1001, 1002], "Online_url" : [' ...

Struggling to upload image to Canvas with React and Next.js

I have been attempting to display an image in my canvas element within a react component. I've tried loading it from various sources - URLs, local repositories, using different syntax forms, but all my efforts have been unsuccessful. The only "progre ...

Tips for integrating Bootstrap 4.5 variables into NextJS seamlessly

I have a new concept in mind - integrating Bootstrap 4.5 into NextJS and customizing variables as demonstrated here: The structure of my files is within the pages folder: _app.js import '../styles/main.scss' function MyApp({ Component, pageProp ...

Tips on addressing this specific popup issue that is exclusive to Firefox

I am currently working on a web automation project for my learning purposes with the website . While using Selenium with the Firefox browser, I encountered a popup that I have been unable to block even after trying various options. Any assistance or advi ...

Execute a post request upon clicking with NEXT JS, while also firing off a get request

I'm facing an issue where I need to post and get my data when clicking on the same button (similar to writing and displaying comments). However, whenever I click the button, everything seems to be working fine but a request with a 304 status code star ...

Issue with lack of data refresh upon button click in tkinter with Python 3

How can I modify this code to make it functional? import os import time import random import sys import string import tkinter as tk root = tk.Tk() root.geometry("400x400") root.title("RandomPass v1.0") welcome = tk.Label(root, text="Welcome to RandomPas ...

Getting WebElement in ItestListener can be achieved by using the WebDriver object provided

How can I retrieve the WebElement in the ITestListener class when a test fails? Is there a method to access the WebElement in the ItestListener during a testfailure? While I have successfully retrieved the testclass name and testmethod name, I am unsure ...

Is it possible to view the code within the .js files located in the api directory of NextJS using web browsers?

Is it possible to view the code of ".js files" in the "api folder" of NextJS using browsers? I came across a post on Stack Overflow where someone asked if Next.js API is back-end, and one of the answers stated: The back-end or server-side of Next.js res ...

Is there a way to automatically launch the Google Chrome devtools?

Is there a method to open the devtools window using a Selenium script even though Selenium 2 closes it, which contains my emulator profile saved under my user profile for chrome? For more information on the issue of the devtools window closing, please vis ...

When utilizing React, if you have set up a useEffect with a cleanup function that is not triggered by external links

When working with React const componentA = ()=>{ const [loading,setLoading]=useState(false); useEffect(()=>{ const dummyVariable="nothing"; return ()=>{ console.log("Component unmounted"); setLoading(fa ...

The function 'next build' is malfunctioning when attempting to create a build for my nextJS application

While attempting to create a nextJS application, I encountered a recurring issue: next build - info Creating an optimized production build - info Compiled successfully - info Linting and checking validity of types - info Collecting page data [ ] - ...

Incorporate tags from SciKit Learn forecasting into your analysis

After successfully generating predictions based on the provided dataset, I am now exploring ways to map these predictions back to the TEAM labels using Python 3, Pandas, and SciKit Learn. Here is a snippet of the sample data: Team A B C Score Red ...

Disabling file-system routing in Next.js is a crucial step for optimizing

I'm a bit confused about the documentation's explanation of setting the useFileSystemPublicRoutes configuration option to false in Next.js. It mentions that this prevents routing based on files in the /pages directory, but the details are not ver ...

Error encountered while attempting to send a delete request to MongoDB due to connection refusal

Recently, I've been diving into a Next.js tutorial that involves working with MongoDB. Everything seems to be running smoothly when testing my API endpoints with Postman. POST, GET, and DELETE requests all go through without any hiccups. However, thi ...