Skip to content

Commit

Permalink
Add page for making a request with query parameters (#227)
Browse files Browse the repository at this point in the history
We now have a page for making requests directly with query string
parameters. For example, you can make an `eth_getLogs` request by
navigation to:

`[test dapp path]/request.html?method=eth_getLogs&params=[{}]`

This can be useful for testing RPC methods not covered by the test
dapp functionality, or for e2e testing (especially on mobile, where
clicking elements on the page can be challenging).

---------

Co-authored-by: legobeat <[email protected]>
  • Loading branch information
Gudahtt and legobeat authored May 1, 2023
1 parent ca45471 commit bc9c170
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 3 deletions.
6 changes: 6 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ module.exports = {
sourceType: 'module',
},
},
{
files: ['src/request.js'],
parserOptions: {
sourceType: 'script',
},
},
],

ignorePatterns: ['!.eslintrc.js', 'dist'],
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ If you wish to use this dapp in your e2e tests, install this package and set up
static-server node_modules/@metamask/test-dapp/dist --port 9011
```

The main page of the test dapp includes a simple UI featuring buttons for common dapp interactions.

There is a second page (`request.html`) that allows making requests directly to the provider using query parameters. This provides a simple way of testing RPC methods using an in-page provider.

It can be used by navigating to `/request.html?method=${METHOD}&params=${PARAMS}` (e.g. `/request.html?method=eth_getLogs&params=[{ "address": "0x0000000000000000000000000000000000000000" }]`). The page will make a request with the given RPC method and parameters using `ethereum.request`, and report the result as plain text.

## Contributing

### Setup
Expand Down
2 changes: 1 addition & 1 deletion src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,6 @@ <h4 class="card-title">
</section>
</main>

<script src="bundle.js" defer></script>
<script src="main.js" defer></script>
</body>
</html>
15 changes: 15 additions & 0 deletions src/request.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<html>
<head>
<meta charset="UTF-8" />
<title>E2E Test Dapp - Send Individual Request</title>
<link rel="icon" type="image/svg" href="metamask-fox.svg" />
</head>

<body>
<main>
Initializing
</main>

<script src="request.js" defer></script>
</body>
</html>
97 changes: 97 additions & 0 deletions src/request.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/**
* Get the `main` section of the page, ensuring that it is the only
* one present.
*/
function getMainElement() {
const mainElements = document.getElementsByTagName('main');

if (mainElements.length === 0) {
throw new Error('Main element not found');
} else if (mainElements.length > 1) {
throw new Error('Multiple main elements found');
}
return mainElements[0];
}

/**
* Get request data from the query string.
*
* @returns {object} The request data.
*/
function getRequestData() {
const queryString = window.location.search;

if (queryString.length === 0) {
throw new Error('Request invalid: query string empty');
}

const searchParams = new URLSearchParams(queryString);
const method = searchParams.get('method');

if (method === null) {
throw new Error('Request invalid: method not provided in query string');
}

const rawParams = searchParams.get('params');

let params;
if (rawParams !== null) {
try {
params = JSON.parse(rawParams);
} catch (error) {
throw new Error('Request invalid: failed to parse params', {
cause: error,
});
}

if (params === null) {
throw new Error(`Request invalid: params parsed as null`);
} else if (typeof params !== 'object') {
throw new Error(
`Request invalid: params parsed as type '${typeof params}'`,
);
}
}

const request = { method };
if (params) {
request.params = params;
}
return request;
}

/**
* Run the request encoded in the query parameters.
*/
async function main() {
const mainElement = getMainElement();

/**
* Log a message, and set it on the page.
*
* @param {string} message - The message to log and set on the page.
*/
function logAndSet(message) {
console.log(message);
mainElement.innerText = message;
}

try {
if (!window.ethereum) {
throw new Error('Provider not found');
}

const requestData = getRequestData();

logAndSet(`Sending request: ${JSON.stringify(requestData)}`);

const result = await window.ethereum.request(requestData);

logAndSet(`Response: ${JSON.stringify(result)}`);
} catch (error) {
mainElement.innerText = error.message || 'Unknown error';
throw error;
}
}

main().catch(console.error);
6 changes: 4 additions & 2 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ const DIST = path.resolve(__dirname, 'dist');
module.exports = {
devtool: 'eval-source-map',
mode: 'development',
entry: './src/index.js',
entry: {
main: './src/index.js',
request: './src/request.js',
},
output: {
filename: 'bundle.js',
path: DIST,
publicPath: DIST,
},
Expand Down

0 comments on commit bc9c170

Please sign in to comment.