Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into issue-#1560
Browse files Browse the repository at this point in the history
  • Loading branch information
GrandSchtroumpf committed Jan 22, 2025
2 parents 3f361f0 + 23aed2f commit b1ec9e5
Show file tree
Hide file tree
Showing 241 changed files with 6,260 additions and 1,698 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ The file `common.ts` with type [`AppConfig`](src/config/types.ts) contains impor
- `ui`
- `priceChart`: use `tradingView` chart or `native` chart for token pair price history. You need to provide a backend with price history endpoint to support `native` view.
- `useGradientBranding`: Flag to enable gradient styles for buttons.
- `tradeCount`: Display the amount of trades in the explorer page.

#### Gas token different than native token

Expand Down
1,486 changes: 0 additions & 1,486 deletions e2e/mocks/tokenLists.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions e2e/pages/simulator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { mockApi } from '../utils/mock-api';
import {
DebugDriver,
removeFork,
setupFork,
setupVirtualNetwork,
setupLocalStorage,
} from '../utils/DebugDriver';
import { CreateStrategyTestCase } from '../utils/simulator';
Expand Down Expand Up @@ -196,8 +196,8 @@ test.describe('Simulator', () => {
test.beforeEach(async ({ page }, testInfo) => {
await mockApi(page);
await mockDate(page, '2024-02-26T00:00:00.000Z');
await setupFork(testInfo);
await setupLocalStorage(page, testInfo);
const vNet = await setupVirtualNetwork(testInfo);
await setupLocalStorage(page, vNet.rpcs[0].url);
const debug = new DebugDriver(page);
await debug.visit();
});
Expand Down
6 changes: 3 additions & 3 deletions e2e/pages/strategy.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { mockApi } from '../utils/mock-api';
import {
DebugDriver,
removeFork,
setupFork,
setupVirtualNetwork,
setupLocalStorage,
} from '../utils/DebugDriver';
import {
Expand Down Expand Up @@ -656,8 +656,8 @@ const testDescription = (testCase: CreateStrategyTestCase) => {
test.describe('Strategies', () => {
test.beforeEach(async ({ page }, testInfo) => {
await mockApi(page);
await setupFork(testInfo);
await setupLocalStorage(page, testInfo);
const vNet = await setupVirtualNetwork(testInfo);
await setupLocalStorage(page, vNet.rpcs[0].url);
const debug = new DebugDriver(page);
await debug.visit();
await debug.setupImposter();
Expand Down
6 changes: 3 additions & 3 deletions e2e/pages/trade.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { mockApi } from '../utils/mock-api';
import {
DebugDriver,
removeFork,
setupFork,
setupVirtualNetwork,
setupLocalStorage,
} from '../utils/DebugDriver';
import { TradeDriver } from '../utils/TradeDriver';
Expand Down Expand Up @@ -90,8 +90,8 @@ test.describe('Trade', () => {
test.beforeEach(async ({ page }, testInfo) => {
testInfo.setTimeout(90_000);
await mockApi(page);
await setupFork(testInfo);
await setupLocalStorage(page, testInfo);
const vNet = await setupVirtualNetwork(testInfo);
await setupLocalStorage(page, vNet.rpcs[0].url);
const debug = new DebugDriver(page);
await debug.visit();
await debug.setupImposter();
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions e2e/tests/strategy/disposable/edit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ export const editPrice = (testCase: CreateStrategyTestCase) => {

const tooltip = await strategy.priceTooltip(direction);
if (setting === 'limit') {
expect(tooltip.price()).toHaveText(output.min);
await expect(tooltip.price()).toHaveText(output.min);
} else {
expect(tooltip.minPrice()).toHaveText(output.min);
expect(tooltip.maxPrice()).toHaveText(output.max);
await expect(tooltip.minPrice()).toHaveText(output.min);
await expect(tooltip.maxPrice()).toHaveText(output.max);
}
});
};
52 changes: 31 additions & 21 deletions e2e/utils/DebugDriver.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,48 @@
import { Page, TestInfo } from '@playwright/test';
import { waitFor } from './../utils/operators';
import {
CreateForkBody,
createFork,
forkRpcUrl,
deleteFork,
createVirtualNetwork,
deleteVirtualNetwork,
CreateVirtualNetworkBody,
} from './../utils/tenderly';
import { Wallet } from 'ethers';
import { CreateStrategyTestCase, toDebugStrategy } from './strategy';
import { TokenApprovalDriver } from './TokenApprovalDriver';
import mockLocalStorage from '../mocks/localstorage.json';

const forkConfig: CreateForkBody = {
network_id: '1',
alias: 'E2E-CI',
// Sep-12-2023
block_number: 18120000,
const vNetConfig: CreateVirtualNetworkBody = {
slug: 'e2e-ci',
display_name: 'E2E-CI',
fork_config: {
network_id: 1,
block_number: '18120000',
},
virtual_network_config: {
chain_config: {
chain_id: 1,
},
},
sync_state_config: {
enabled: false,
},
explorer_page_config: {
enabled: false,
verification_visibility: 'bytecode',
},
};

export const setupFork = async (testInfo: TestInfo) => {
const fork = await createFork(forkConfig);
process.env[`TENDERLY_FORK_ID_TEST_${testInfo.testId}`] = fork.id;
export const setupVirtualNetwork = async (testInfo: TestInfo) => {
const vNet = await createVirtualNetwork(structuredClone(vNetConfig));
process.env[`TENDERLY_FORK_ID_TEST_${testInfo.testId}`] = vNet.id;
return vNet;
};

export const setupLocalStorage = async (page: Page, testInfo: TestInfo) => {
const forkId = process.env[`TENDERLY_FORK_ID_TEST_${testInfo.testId}`];
if (!forkId)
throw new Error('Fork should be created before setting the RPC URL');
const tenderlyRpc = forkRpcUrl(forkId);
export const setupLocalStorage = async (page: Page, tenderlyRpc: string) => {
// We need to be on a page to set localstorage so we create an empty page
await page.route(testInfo.testId, (route) => {
await page.route('empty', (route) => {
return route.fulfill({ status: 200, contentType: 'text/plain', body: '' });
});
await page.goto(testInfo.testId);
await page.goto('empty');
const storage = { ...mockLocalStorage, tenderlyRpc };
return page.evaluate((storage) => {
// each value is stringified to match lsservice
Expand All @@ -46,8 +56,8 @@ export const setupLocalStorage = async (page: Page, testInfo: TestInfo) => {
};

export const removeFork = async (testInfo: TestInfo) => {
const forkId = process.env[`TENDERLY_FORK_ID_TEST_${testInfo.testId}`];
if (forkId) await deleteFork(forkId);
const id = process.env[`TENDERLY_FORK_ID_TEST_${testInfo.testId}`];
if (id) await deleteVirtualNetwork(id);
};

interface ImposterConfig {
Expand Down
14 changes: 2 additions & 12 deletions e2e/utils/simulator/CreateSimulationDriver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ import {
} from './utils';
import { CreateStrategyTestCase, StrategyType } from './types';
import { RangeOrder, debugTokens, Direction, Setting } from '../types';
import { waitModalClose, waitModalOpen, waitTooltipsClose } from '../modal';
import { screenshot, shouldTakeScreenshot, waitFor } from '../operators';
import { MainMenuDriver } from '../MainMenuDriver';
import { waitModalClose, waitModalOpen } from '../modal';
import { screenshot, waitFor } from '../operators';
import { dayjs } from '../../../src/libs/dayjs';

export class CreateSimulationDriver {
Expand Down Expand Up @@ -180,15 +179,6 @@ export class CreateSimulationDriver {
const btn = this.page.getByTestId('start-simulation-btn');
await expect(btn).toHaveText('Start Simulation');
await expect(btn).toBeEnabled();
if (shouldTakeScreenshot) {
const mainMenu = new MainMenuDriver(this.page);
await mainMenu.hide();
await waitTooltipsClose(this.page);
const form = this.getForm();
const path = screenshotPath(this.testCase, 'form');
await screenshot(form, path);
await mainMenu.show();
}
return btn.click();
}
}
86 changes: 56 additions & 30 deletions e2e/utils/tenderly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,12 @@ const TENDERLY_ACCESS_KEY = process.env['TENDERLY_ACCESS_KEY'];
if (!TENDERLY_ACCESS_KEY)
throw new Error('No TENDERLY_ACCESS_KEY provided in .env');

const baseUrl = `https://api.tenderly.co/api/v1/account/${TENDERLY_ACCOUNT}/project/${TENDERLY_PROJECT}/fork`;
const baseUrl = `https://api.tenderly.co/api/v1/account/${TENDERLY_ACCOUNT}/project/${TENDERLY_PROJECT}/vnets`;
const headers = {
'Content-Type': 'application/json',
'X-Access-Key': TENDERLY_ACCESS_KEY,
};

export const forkRpcUrl = (forkId: string) => {
return `https://rpc.tenderly.co/fork/${forkId}`;
};

interface ChainConfig {
type: string; // 'ethereum' | ...
chain_id: number;
Expand Down Expand Up @@ -61,55 +57,80 @@ interface Fork {
shared: boolean;
}

export interface CreateForkBody {
/** ChainID in decimal: "1" for mainnet */
network_id: string;
alias?: string;
block_number?: number;
chain_config?: Partial<ChainConfig>;
/** See https://docs.tenderly.co/reference/api#/operations/createVnet */
export interface CreateVirtualNetworkBody {
slug: string;
display_name?: string;
description?: string;
fork_config: {
network_id: number;
block_number: string;
};
virtual_network_config: {
chain_config: {
chain_id: number;
};
};
sync_state_config?: {
enabled?: boolean;
};
explorer_page_config?: {
enabled?: boolean;
verification_visibility?: 'bytecode' | 'src' | 'abi';
};
}

export interface CreateForkResponse {
simulation_fork: Fork;
root_transaction: any;
/** See https://docs.tenderly.co/reference/api#/operations/createVnet#Responses */
export interface CreateVirtualNetworkResponse {
id: string;
slug: string;
rpcs: {
url: string;
name: string;
}[];
}

export const createFork = async (body: CreateForkBody) => {
const res = await fetch(baseUrl, {
export const createVirtualNetwork = async (body: CreateVirtualNetworkBody) => {
body.slug += `-${crypto.randomUUID()}`;
const req = new Request(baseUrl, {
method: 'POST',
body: JSON.stringify(body),
headers,
});
if (!res.ok) return tenderlyError(res);
const result: CreateForkResponse = await res.json();
return result.simulation_fork;
const clone = req.clone();
const res = await fetch(req);
if (!res.ok) return tenderlyError(clone, res);
return res.json() as Promise<CreateVirtualNetworkResponse>;
};

export interface GetForkResponse {
simulation_fork: Fork;
}

export const waitForTenderlyRpc = (page: Page, timeout?: number) => {
const tenderlyRegExp = /.*rpc\.tenderly\.co\/fork.*$/;
const tenderlyRegExp = /.*rpc\.tenderly\.co.*$/;
return page.waitForResponse(tenderlyRegExp, { timeout });
};

export const getFork = async (forkId: string) => {
const res = await fetch(`${baseUrl}/${forkId}`, {
export const getVirtualNetwork = async (id: string) => {
const req = new Request(`${baseUrl}/${id}`, {
method: 'GET',
headers,
});
if (!res.ok) return tenderlyError(res);
const result: GetForkResponse = await res.json();
return result.simulation_fork;
const clone = req.clone();
const res = await fetch(req);
if (!res.ok) return tenderlyError(clone, res);
return res.json();
};

export const deleteFork = async (forkId: string) => {
const res = await fetch(`${baseUrl}/${forkId}`, {
export const deleteVirtualNetwork = async (id: string) => {
const req = new Request(`${baseUrl}/${id}`, {
method: 'DELETE',
headers,
});
if (!res.ok) return tenderlyError(res);
const clone = req.clone();
const res = await fetch(req);
if (!res.ok) return tenderlyError(clone, res);
// Delete returns No Content
};

Expand All @@ -121,8 +142,13 @@ interface TenderlyError {
interface TenderlyErrorResponse {
error: TenderlyError;
}
const tenderlyError = async (res: Response) => {
const tenderlyError = async (req: Request, res: Response) => {
const { status, statusText } = res;
const { error }: TenderlyErrorResponse = await res.json();
throw new Error(`[${status} ${statusText}] ${error?.message}`);
const body = await req.text();
const message = {
res: `[${status} ${statusText}] ${error?.message}`,
req: `[${req.url}] ${body}`,
};
throw new Error(JSON.stringify(message));
};
2 changes: 1 addition & 1 deletion playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export default defineConfig({

expect: {
// Maximum time expect() should wait for the condition to be met.
timeout: 10000,
timeout: 10_000,
},

/* Run your local dev server before starting the tests */
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit b1ec9e5

Please sign in to comment.