diff --git a/.circleci/config.yml b/.circleci/config.yml index f0fe9281e9..e33ffeb840 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -130,7 +130,7 @@ jobs: name: "Run tests" command: | cd apps/remixdesktop/ - yarn run build:e2e && yarn run test && yarn run test:isogit + yarn run build:e2e && yarn run test:offline && yarn run test && yarn run test:isogit build-remixdesktop-linux: machine: @@ -267,6 +267,7 @@ jobs: cd "apps/remixdesktop/" yarn -v sleep 15 + yarn run test:offline yarn run test yarn run test:isogit shell: powershell.exe @@ -508,7 +509,7 @@ jobs: command: | nvm use 20 cd apps/remixdesktop - yarn run test && yarn run test:isogit + yarn run test:offline && yarn run test && yarn run test:isogit uploadartifacts: docker: diff --git a/apps/remixdesktop/package.json b/apps/remixdesktop/package.json index 51e774dc1a..3f9fda914c 100644 --- a/apps/remixdesktop/package.json +++ b/apps/remixdesktop/package.json @@ -30,6 +30,7 @@ "postinstall": "electron-builder install-app-deps", "test": "yarn run build:e2e && nightwatch --config build-e2e/remixdesktop/test/nighwatch.app.js", "test:isogit": "yarn run test --useIsoGit --test build-e2e/remixdesktop/test/tests/app/git.test.js", + "test:offline": "yarn run test --useOffline --test build-e2e/remixdesktop/test/tests/app/offline.test.js", "build:e2e": "tsc -p tsconfig.e2e.json" }, "devDependencies": { diff --git a/apps/remixdesktop/src/plugins/compilerLoader.ts b/apps/remixdesktop/src/plugins/compilerLoader.ts index 7e60b38043..846ab4641f 100644 --- a/apps/remixdesktop/src/plugins/compilerLoader.ts +++ b/apps/remixdesktop/src/plugins/compilerLoader.ts @@ -1,16 +1,19 @@ -import {Profile} from '@remixproject/plugin-utils' -import {ElectronBasePlugin, ElectronBasePluginClient} from '@remixproject/plugin-electron' +import { Profile } from '@remixproject/plugin-utils' +import { ElectronBasePlugin, ElectronBasePluginClient } from '@remixproject/plugin-electron' import fs from 'fs/promises' import axios from 'axios' import express from 'express' -import {cacheDir} from '../utils/config' +import { cacheDir } from '../utils/config' export const baseURLBin = 'https://binaries.soliditylang.org/bin' export const baseURLWasm = 'https://binaries.soliditylang.org/wasm' const appExpress = express() +// used in e2e tests +const useOffline = process.argv.includes('--useOffline'); + console.log('cacheDir', cacheDir) appExpress.use(express.static(cacheDir)) const server = appExpress.listen(0, () => { @@ -28,9 +31,9 @@ export class CompilerLoaderPlugin extends ElectronBasePlugin { constructor() { super(profile, clientProfile, CompilerLoaderPluginClient) this.methods = [...super.methods] - ;(async () => { - await getLists() - })() + ; (async () => { + await getLists() + })() } @@ -73,7 +76,7 @@ class CompilerLoaderPluginClient extends ElectronBasePluginClient { async downloadCompiler(url: string): Promise { console.log('downloadCompiler', url) - if(url.includes('localhost')) return + if (url.includes('localhost')) return const plugin = this try { const fileName = url.split('/').pop() @@ -127,7 +130,7 @@ class CompilerLoaderPluginClient extends ElectronBasePluginClient { async getJsonBinData() { const lists = await this.getLists() - + this.solJsonBinData = { baseURLWasm: 'http://localhost:' + (server.address() as any).port + '/compilers', baseURLBin: 'http://localhost:' + (server.address() as any).port + '/compilers', @@ -137,11 +140,11 @@ class CompilerLoaderPluginClient extends ElectronBasePluginClient { const localCompilers = await this.listCompilers() this.solJsonBinData.wasmList && (this.solJsonBinData.wasmList = this.solJsonBinData.wasmList.map((item) => { - localCompilers.includes(item.path) ? (item.wasmURL = 'http://localhost:' + (server.address() as any).port + '/compilers/') && (item.isDownloaded=true) : (item.wasmURL = baseURLWasm) && (item.isDownloaded = false) + localCompilers.includes(item.path) ? (item.wasmURL = 'http://localhost:' + (server.address() as any).port + '/compilers/') && (item.isDownloaded = true) : (item.wasmURL = baseURLWasm) && (item.isDownloaded = false) return item })) this.solJsonBinData.binList && (this.solJsonBinData.binList = this.solJsonBinData.binList.map((item) => { - localCompilers.includes(item.path) ? (item.binURL = 'http://localhost:' + (server.address() as any).port + '/compilers/') && (item.isDownloaded=true) : (item.binURL = baseURLBin) && (item.isDownloaded = false) + localCompilers.includes(item.path) ? (item.binURL = 'http://localhost:' + (server.address() as any).port + '/compilers/') && (item.isDownloaded = true) : (item.binURL = baseURLBin) && (item.isDownloaded = false) return item })) this.emit('jsonBinDataLoaded', this.solJsonBinData) @@ -156,17 +159,19 @@ const getLists = async () => { let binData let wasmData - try { - const binRes = await axios.get(baseURLBin + '/list.json') - await fs.writeFile(cacheDir + '/binlist.json', JSON.stringify(binRes.data, null, 2)) - binData = binRes.data - } catch (e) {} - - try { - const wasmRes = await axios.get(baseURLWasm + '/list.json') - await fs.writeFile(cacheDir + '/wasmlist.json', JSON.stringify(wasmRes.data, null, 2)) - wasmData = wasmRes.data - } catch (e) {} + if (!useOffline) { + try { + const binRes = await axios.get(baseURLBin + '/list.json') + await fs.writeFile(cacheDir + '/binlist.json', JSON.stringify(binRes.data, null, 2)) + binData = binRes.data + } catch (e) { } + + try { + const wasmRes = await axios.get(baseURLWasm + '/list.json') + await fs.writeFile(cacheDir + '/wasmlist.json', JSON.stringify(wasmRes.data, null, 2)) + wasmData = wasmRes.data + } catch (e) { } + } if (!wasmData) { try { diff --git a/apps/remixdesktop/test/nighwatch.app.ts b/apps/remixdesktop/test/nighwatch.app.ts index 1338e4fe0b..5671f625b7 100644 --- a/apps/remixdesktop/test/nighwatch.app.ts +++ b/apps/remixdesktop/test/nighwatch.app.ts @@ -3,6 +3,7 @@ const os = require('os'); const http = require('http'); const useIsoGit = process.argv.includes('--useIsoGit'); +const useOffline = process.argv.includes('--useOffline'); // Function to check if localhost:8080 is active function checkLocalhost8080Active(callback) { @@ -84,6 +85,7 @@ module.exports = { let args = process.env.CIRCLECI ? ["--e2e"] : ["--e2e-local"]; if(useIsoGit) args = [...args, '--useIsoGit']; + if(useOffline) args = [...args, '--useOffline']; if(!process.env.CIRCLECI){ checkLocalhost8080Active((isActive)=>{ diff --git a/apps/remixdesktop/test/tests/app/offline.test.ts b/apps/remixdesktop/test/tests/app/offline.test.ts new file mode 100644 index 0000000000..a462626176 --- /dev/null +++ b/apps/remixdesktop/test/tests/app/offline.test.ts @@ -0,0 +1,41 @@ +import { NightwatchBrowser } from 'nightwatch' + + +module.exports = { + before: function (browser: NightwatchBrowser, done: VoidFunction) { + done() + }, + 'open default template': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000) + .waitForElementVisible('button[data-id="landingPageImportFromTemplate"]') + .click('button[data-id="landingPageImportFromTemplate"]') + .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') + .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') + .click('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') + .pause(3000) + .windowHandles(function (result) { + console.log(result.value) + browser.switchWindow(result.value[1]) + .waitForElementVisible('*[data-id="treeViewLitreeViewItemtests"]') + .click('*[data-id="treeViewLitreeViewItemtests"]') + .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts"]') + .click('*[data-id="treeViewLitreeViewItemcontracts"]') + .waitForElementVisible('[data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]') + .openFile('contracts/1_Storage.sol') + .waitForElementVisible('*[id="editorView"]', 10000) + .getEditorValue((content) => { + browser.assert.ok(content.includes('function retrieve() public view returns (uint256){')) + }) + }) + }, + 'compile storage': function (browser: NightwatchBrowser) { + browser + .clickLaunchIcon('solidity') + .pause(1000) + .waitForElementVisible('*[data-id="compilerContainerCompileBtn"]') + .click('[data-id="compilerContainerCompileBtn"]') + .clickLaunchIcon('filePanel') + .verifyContracts(['Storage']) + } +} \ No newline at end of file