diff --git a/apps/remixdesktop/aftersign.js b/apps/remixdesktop/aftersign.js index 5ea850e164..bb1e2102c9 100644 --- a/apps/remixdesktop/aftersign.js +++ b/apps/remixdesktop/aftersign.js @@ -1,66 +1,69 @@ const { notarize } = require('@electron/notarize') const fs = require('fs') const { exec } = require('child_process') // Import the exec function -exports.default = async function notarizing(context) { - const { electronPlatformName, appOutDir } = context // Provided by electron-builder - console.log('NOTARIZING') +// read the environment variables from process - if (electronPlatformName !== 'darwin' || !process.env.CIRCLE_BRANCH) { - return - } +console.log(process.env.DO_NOT_NOTARIZE) - const appName = context.packager.appInfo.productFilename - const appPath = `${appOutDir}/${appName}.app` - - // Function to promisify the exec command - function execShellCommand(cmd) { - return new Promise((resolve, reject) => { - exec(cmd, (error, stdout, stderr) => { - if (error) { - reject(new Error(`Error: ${error.message}`)); - return; - } - if (stderr) { - reject(new Error(`Stderr: ${stderr}`)); - return; - } - console.log(`stdout: ${stdout}`); - resolve(stdout); - }); - }); +if (process.env.DO_NOT_NOTARIZE) { + console.log('NOTARIZING DISABLED') + exports.default = async function notarizing(context) { + return [] } +} else { + + exports.default = async function notarizing(context) { + const { electronPlatformName, appOutDir } = context // Provided by electron-builder - // Function to check if the app is stapled - // Async function to check the stapling status - async function checkStapleStatus() { - try { - console.log(`xcrun stapler validate "${appPath}"`) - await execShellCommand(`xcrun stapler validate "${appPath}"`); - console.log('App is already stapled. No action needed.'); - return true - } catch (error) { - console.log(`App is not stapled: ${error.message}`); - return false + console.log('NOTARIZING') + + if (electronPlatformName !== 'darwin' || !process.env.CIRCLE_BRANCH) { + return + } + + const appName = context.packager.appInfo.productFilename + const appPath = `${appOutDir}/${appName}.app` + + // Function to promisify the exec command + function execShellCommand(cmd) { + return new Promise((resolve, reject) => { + exec(cmd, (error, stdout, stderr) => { + if (error) { + reject(new Error(`Error: ${error.message}`)); + return; + } + if (stderr) { + reject(new Error(`Stderr: ${stderr}`)); + return; + } + console.log(`stdout: ${stdout}`); + resolve(stdout); + }); + }); } - } + // Function to check if the app is stapled + // Async function to check the stapling status + async function checkStapleStatus() { + try { + console.log(`xcrun stapler validate "${appPath}"`) + await execShellCommand(`xcrun stapler validate "${appPath}"`); + console.log('App is already stapled. No action needed.'); + return true + } catch (error) { + console.log(`App is not stapled: ${error.message}`); + return false + } + } - async function runNotarize() { - console.log('NOTARIZING + ', `xcrun stapler staple "${appPath}"`) - console.log({ - appBundleId: 'org.ethereum.remix-ide', // Your app's bundle ID - appPath: `${appOutDir}/${appName}.app`, // Path to your .app - appleId: process.env.APPLE_ID, // Your Apple ID - appleIdPassword: process.env.APPLE_ID_PASSWORD, // App-specific password - teamId: process.env.APPLE_TEAM_ID, // Your Apple Developer team ID (optional) - }) + async function runNotarize() { - try { - const r = await notarize({ + console.log('NOTARIZING + ', `xcrun stapler staple "${appPath}"`) + console.log({ appBundleId: 'org.ethereum.remix-ide', // Your app's bundle ID appPath: `${appOutDir}/${appName}.app`, // Path to your .app appleId: process.env.APPLE_ID, // Your Apple ID @@ -68,23 +71,34 @@ exports.default = async function notarizing(context) { teamId: process.env.APPLE_TEAM_ID, // Your Apple Developer team ID (optional) }) - console.log(r) + try { + const r = await notarize({ + appBundleId: 'org.ethereum.remix-ide', // Your app's bundle ID + appPath: `${appOutDir}/${appName}.app`, // Path to your .app + appleId: process.env.APPLE_ID, // Your Apple ID + appleIdPassword: process.env.APPLE_ID_PASSWORD, // App-specific password + teamId: process.env.APPLE_TEAM_ID, // Your Apple Developer team ID (optional) + }) - // Stapling the app - console.log('STAPLING', `xcrun stapler staple "${appPath}"`) + console.log(r) - await execShellCommand(`xcrun stapler staple "${appPath}"`) + // Stapling the app + console.log('STAPLING', `xcrun stapler staple "${appPath}"`) - } catch (error) { - console.error('Error during notarization:', error) - } + await execShellCommand(`xcrun stapler staple "${appPath}"`) - } + } catch (error) { + console.error('Error during notarization:', error) + throw new Error('Error during notarization', error) + } - if(!await checkStapleStatus()){ - await runNotarize() - await checkStapleStatus() - }else{ - return [] + } + + if (!await checkStapleStatus()) { + await runNotarize() + await checkStapleStatus() + } else { + return [] + } } -} +} \ No newline at end of file diff --git a/apps/remixdesktop/insiders.json b/apps/remixdesktop/insiders.json index 0968d6df7b..4b5bd39c00 100644 --- a/apps/remixdesktop/insiders.json +++ b/apps/remixdesktop/insiders.json @@ -5,7 +5,8 @@ "generateUpdatesFilesForAllChannels": false, "icon": "assets", "files": [ - "build/**/*" + "build/**/*", + "node_modules/node-pty/**/*" ], "afterSign": "aftersign.js", "afterAllArtifactBuild": "afterbuild.js", diff --git a/apps/remixdesktop/notarizedmg.sh b/apps/remixdesktop/notarizedmg.sh index e621d3a422..3522476f08 100644 --- a/apps/remixdesktop/notarizedmg.sh +++ b/apps/remixdesktop/notarizedmg.sh @@ -11,7 +11,7 @@ echo $DMG_PATHS xcrun notarytool store-credentials "notarytool-password" \ --apple-id ${APPLE_ID} \ --team-id ${APPLE_TEAM_ID} \ - --password ${APPLE_ID_PASSWORD} + --password ${APPLE_ID_PASSWORD} || exit 1 # Use jq to parse the DMGs array and read each line while IFS= read -r DMG_PATH; do diff --git a/apps/remixdesktop/package.json b/apps/remixdesktop/package.json index dab27c67a3..edbeb7e263 100644 --- a/apps/remixdesktop/package.json +++ b/apps/remixdesktop/package.json @@ -1,7 +1,7 @@ { "name": "remixdesktop", - "version": "1.0.5-insiders", - "main": "build/apps/remixdesktop/src/main.js", + "version": "1.0.8-insiders", + "main": "build/main.js", "license": "MIT", "type": "commonjs", "description": "Remix IDE Desktop", @@ -13,6 +13,9 @@ "name": "Remix Team", "email": "remix@ethereum.org" }, + "engines": { + "node": "20.2.0" + }, "bugs": { "url": "https://github.com/ethereum/remix-project/issues" }, @@ -22,15 +25,17 @@ "category": "public.app-category.productivity" }, "scripts": { - "start:dev": "tsc && cp -R node_modules/yarn build/tools/ && cross-env NODE_ENV=development electron --inspect=5858 .", - "start:production": "tsc && && cp -R node_modules/yarn build/tools/ && cross-env NODE_ENV=production electron .", - "dist": "tsc && cp -R node_modules/yarn build/tools/ && electron-builder -p never", + "start:dev": "yarn webpack --config webpack.config.js && electron --inspect=5858 .", + "start:production": "cross-env NODE_ENV=production yarn webpack --config webpack.config.js && electron .", + "dist": "cross-env NODE_ENV=production yarn webpack --config webpack.config.js && electron-builder -p never", + "tscbuild": "tsc && cp -R node_modules/yarn build/tools/ && electron-builder -p never", + "esbuild": "cross-env NODE_ENV=production node esbuild.js && electron-builder -p never", "installRipGrepMacOXx64": "rm -rf node_modules/@vscode/ripgrep/bin && npm_config_arch=x64 node node_modules/@vscode/ripgrep/lib/postinstall.js", "installRipGrepMacOXarm64": "rm -rf node_modules/@vscode/ripgrep/bin && npm_config_arch=arm64 node node_modules/@vscode/ripgrep/lib/postinstall.js", "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", + "test:isogit": "yarn run test --use-isogit", + "test:offline": "yarn run test --use-offline --test build-e2e/remixdesktop/test/tests/app/offline.test.js", "build:e2e": "tsc -p tsconfig.e2e.json" }, "devDependencies": { @@ -38,18 +43,24 @@ "@types/byline": "^4.2.35", "@types/express": "^4.17.21", "@types/nightwatch": "^2.3.23", - "@xenova/transformers": "^2.17.2", "chromedriver": "116", "cross-env": "^7.0.3", "deep-equal": "^2.2.3", "electron": "^26.0.0", "electron-builder": "24.9.1", "electron-devtools-installer": "^3.2.0", + "esbuild": "^0.23.1", "nightwatch": "2.3", - "node-fetch": "2.6.1", - "onnxruntime-web": "^1.18.0", + "node-loader": "^2.0.0", "selenium-standalone": "^9.3.1", + "tree-kill": "^1.2.2", + "ts-loader": "^9.5.1", + "tsconfig-paths-webpack-plugin": "^4.1.0", "typescript": "^5.1.3", + "webpack": "^5.92.1", + "webpack-cli": "^5.1.4", + "webpack-merge": "^6.0.1", + "webpack-node-externals": "^3.0.0", "yarn": "^1.22.21" }, "dependencies": { @@ -61,25 +72,17 @@ "@remixproject/plugin-electron": "0.3.43", "@vscode/ripgrep": "^1.15.6", "add": "^2.0.6", - "axios": "^1.6.8", + "axios": "^1.7.4", "byline": "^5.0.0", "chokidar": "^3.5.3", - "create-require": "^1.1.1", "electron-updater": "^6.1.8", - "esm": "^3.2.25", - "express": "^4.19.2", - "i": "^0.3.7", + "express": "^4.20.0", "isomorphic-git": "^1.24.2", "matomo-tracker": "^2.2.4", - "node-pty": "^0.10.1", - "npm": "^10.8.1", + "node-pty": "^1.0.0", + "octokit": "^3.1.2", "semver": "^7.5.4" }, - "imports": { - "#transformers": { - "require": "@xenova/transformers" - } - }, "optionalDependencies": { "@remix-project/remix-ws-templates": "^1.0.27" } diff --git a/apps/remixdesktop/run_ci_test.sh b/apps/remixdesktop/run_ci_test.sh index 3020b0daf1..9b3ebfcdd1 100755 --- a/apps/remixdesktop/run_ci_test.sh +++ b/apps/remixdesktop/run_ci_test.sh @@ -4,13 +4,12 @@ TEST_EXITCODE=0 yarn run build:e2e && node ./splice_tests.js TESTFILES=$(node ./splice_tests.js | circleci tests split --split-by=timings) for TESTFILE in $TESTFILES; do - yarn run test --test ./build-e2e/remixdesktop/test/tests/app/${TESTFILE} || TEST_EXITCODE=1 + yarn run test --test ./build-e2e/remixdesktop/test/tests/app/${TESTFILE} || yarn run test --test ./build-e2e/remixdesktop/test/tests/app/${TESTFILE} || TEST_EXITCODE=1 done -if [ "$CIRCLE_NODE_INDEX" -eq 0 ]; then - yarn test:isogit -elif [ "$CIRCLE_NODE_INDEX" -eq 1 ]; then - yarn test:offline + +if [ "$CIRCLE_NODE_INDEX" -eq 1 ]; then + yarn test:offline || TEST_EXITCODE=1 fi echo "$TEST_EXITCODE" diff --git a/apps/remixdesktop/src/lib/remixd.ts b/apps/remixdesktop/src/lib/remixd.ts index 4315da2880..ea3c2afd2b 100644 --- a/apps/remixdesktop/src/lib/remixd.ts +++ b/apps/remixdesktop/src/lib/remixd.ts @@ -28,6 +28,7 @@ export class ElectronBasePluginRemixdClient extends ElectronBasePluginClient { this.onload(async () => { this.on('fs' as any, 'workingDirChanged', async (path: string) => { + console.log('workingDirChanged base remixd', path) this.currentSharedFolder = path }) this.currentSharedFolder = await this.call('fs' as any, 'getWorkingDir') diff --git a/apps/remixdesktop/src/lib/utils.ts b/apps/remixdesktop/src/lib/utils.ts index e406b647b9..1520915d8b 100644 --- a/apps/remixdesktop/src/lib/utils.ts +++ b/apps/remixdesktop/src/lib/utils.ts @@ -19,6 +19,6 @@ function normalizePath (path) { return path } -export { absolutePath } +export { absolutePath, normalizePath } diff --git a/apps/remixdesktop/src/plugins/appUpdater.ts b/apps/remixdesktop/src/plugins/appUpdater.ts index e7a6ff56d8..78abaa3721 100644 --- a/apps/remixdesktop/src/plugins/appUpdater.ts +++ b/apps/remixdesktop/src/plugins/appUpdater.ts @@ -14,7 +14,6 @@ const profile = { export class AppUpdaterPlugin extends ElectronBasePlugin { clients: AppUpdaterPluginClient[] = [] constructor() { - console.log('AppUpdaterPlugin') super(profile, clientProfile, AppUpdaterPluginClient) this.methods = [...super.methods] @@ -78,14 +77,11 @@ const clientProfile: Profile = { class AppUpdaterPluginClient extends ElectronBasePluginClient { constructor(webContentsId: number, profile: Profile) { - console.log('AppUpdaterPluginClient') super(webContentsId, profile) } async onActivation(): Promise { - console.log('onActivation', 'appUpdaterPluginClient') this.onload(async () => { - console.log('onload', 'appUpdaterPluginClient') this.emit('loaded') if(isE2E) return await this.checkForUpdates() diff --git a/apps/remixdesktop/src/plugins/compilerLoader.ts b/apps/remixdesktop/src/plugins/compilerLoader.ts index 846ab4641f..9a74931543 100644 --- a/apps/remixdesktop/src/plugins/compilerLoader.ts +++ b/apps/remixdesktop/src/plugins/compilerLoader.ts @@ -12,7 +12,7 @@ export const baseURLWasm = 'https://binaries.soliditylang.org/wasm' const appExpress = express() // used in e2e tests -const useOffline = process.argv.includes('--useOffline'); +const useOffline = process.argv.includes('--use-offline'); console.log('cacheDir', cacheDir) appExpress.use(express.static(cacheDir)) diff --git a/apps/remixdesktop/src/plugins/fsPlugin.ts b/apps/remixdesktop/src/plugins/fsPlugin.ts index d01235de66..bbf96e0856 100644 --- a/apps/remixdesktop/src/plugins/fsPlugin.ts +++ b/apps/remixdesktop/src/plugins/fsPlugin.ts @@ -32,6 +32,14 @@ const getBaseName = (pathName: string): string => { return path.basename(pathName) } +function onlyUnique(value: recentFolder, index: number, self: recentFolder[]) { + return self.findIndex((rc, index) => rc.path === value.path) === index +} + +const deplucateFolderList = (list: recentFolder[]): recentFolder[] => { + return list.filter(onlyUnique) +} + export class FSPlugin extends ElectronBasePlugin { clients: FSPluginClient[] = [] constructor() { @@ -40,28 +48,28 @@ export class FSPlugin extends ElectronBasePlugin { } async onActivation(): Promise { - const config = await this.call('electronconfig' as any, 'readConfig') + const config = await this.call('electronconfig', 'readConfig') const openedFolders = (config && config.openedFolders) || [] - const recentFolders = (config && config.recentFolders) || [] + const recentFolders: recentFolder[] = (config && config.recentFolders) || [] this.call('electronconfig', 'writeConfig', {...config, - recentFolders: recentFolders, + recentFolders: deplucateFolderList(recentFolders), openedFolders: openedFolders}) const foldersToDelete: string[] = [] - if (openedFolders && openedFolders.length) { - for (const folder of openedFolders) { + if (recentFolders && recentFolders.length) { + for (const folder of recentFolders) { try { - const stat = await fs.stat(folder) + const stat = await fs.stat(folder.path); if (stat.isDirectory()) { // do nothing } } catch (e) { console.log('error opening folder', folder, e) - foldersToDelete.push(folder) + foldersToDelete.push(folder.path) } } if (foldersToDelete.length) { - const newFolders = openedFolders.filter((f: string) => !foldersToDelete.includes(f)) - this.call('electronconfig', 'writeConfig', {recentFolders: newFolders}) + const newFolders = recentFolders.filter((f: recentFolder) => !foldersToDelete.includes(f.path)) + this.call('electronconfig', 'writeConfig', {recentFolders: deplucateFolderList(newFolders)}) } } createWindow() @@ -85,6 +93,13 @@ export class FSPlugin extends ElectronBasePlugin { client.openFolder(path) } } + + openFolderInSameWindow(webContentsId: any, path?: string): void { + const client = this.clients.find((c) => c.webContentsId === webContentsId) + if (client) { + client.openFolderInSameWindow(path) + } + } } const clientProfile: Profile = { @@ -346,6 +361,7 @@ class FSPluginClient extends ElectronBasePluginClient { path, timestamp, }) + config.recentFolders = deplucateFolderList(config.recentFolders) writeConfig(config) } diff --git a/apps/remixdesktop/src/plugins/isoGitPlugin.ts b/apps/remixdesktop/src/plugins/isoGitPlugin.ts index 3aaf610305..201d19b6d4 100644 --- a/apps/remixdesktop/src/plugins/isoGitPlugin.ts +++ b/apps/remixdesktop/src/plugins/isoGitPlugin.ts @@ -1,12 +1,11 @@ -import { PluginClient } from "@remixproject/plugin"; -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 git from 'isomorphic-git' -import { dialog } from "electron"; import http from 'isomorphic-git/http/web' -import { gitProxy } from "../tools/git"; -import { remote } from "../types"; +import {gitProxy} from '../tools/git' +import {isoGit} from '@remix-git' +import {branchDifference, branchInputType, checkoutInputType, cloneInputType, commitChange, commitInputType, compareBranchesInput, currentBranchInput, fetchInputType, initInputType, logInputType, pullInputType, pushInputType, remote, resolveRefInput, statusInput} from '@remix-api' const profile: Profile = { name: 'isogit', @@ -14,7 +13,7 @@ const profile: Profile = { description: 'isogit plugin', } // used in e2e tests -const useIsoGit = process.argv.includes('--useIsoGit'); +const useIsoGit = process.argv.includes('--use-isogit') export class IsoGitPlugin extends ElectronBasePlugin { clients: IsoGitPluginClient[] = [] constructor() { @@ -22,33 +21,18 @@ export class IsoGitPlugin extends ElectronBasePlugin { } startClone(webContentsId: any): void { - const client = this.clients.find(c => c.webContentsId === webContentsId) + const client = this.clients.find((c) => c.webContentsId === webContentsId) if (client) { client.startClone() } } } -const parseInput = (input: any) => { - return { - corsProxy: 'https://corsproxy.remixproject.org/', - http, - onAuth: (url: any) => { - url - const auth = { - username: input.token, - password: '' - } - return auth - } - } -} - const clientProfile: Profile = { name: 'isogit', displayName: 'isogit', description: 'isogit plugin', - methods: ['init', 'localStorageUsed', 'version', 'addremote', 'delremote', 'remotes', 'fetch', 'clone', 'export', 'import', 'status', 'log', 'commit', 'add', 'remove', 'reset', 'rm', 'lsfiles', 'readblob', 'resolveref', 'branches', 'branch', 'checkout', 'currentbranch', 'push', 'pin', 'pull', 'pinList', 'unPin', 'setIpfsConfig', 'zip', 'setItem', 'getItem', 'openFolder'] + methods: ['init', 'localStorageUsed', 'version', 'addremote', 'delremote', 'remotes', 'fetch', 'clone', 'export', 'import', 'status', 'log', 'commit', 'add', 'remove', 'rm', 'readblob', 'resolveref', 'branches', 'branch', 'checkout', 'currentbranch', 'push', 'pin', 'pull', 'pinList', 'unPin', 'setIpfsConfig', 'zip', 'setItem', 'getItem', 'openFolder', 'getCommitChanges', 'compareBranches', 'startClone', 'updateSubmodules'], } class IsoGitPluginClient extends ElectronBasePluginClient { @@ -59,15 +43,15 @@ class IsoGitPluginClient extends ElectronBasePluginClient { this.onload(async () => { this.on('fs' as any, 'workingDirChanged', async (path: string) => { this.workingDir = path - this.gitIsInstalled = await gitProxy.version() ? true : false + this.gitIsInstalled = (await gitProxy.version()) && !useIsoGit ? true : false }) this.workingDir = await this.call('fs' as any, 'getWorkingDir') - this.gitIsInstalled = await gitProxy.version() && !useIsoGit ? true : false + this.gitIsInstalled = (await gitProxy.version()) && !useIsoGit ? true : false }) } async version() { - return gitProxy.version() + return this.gitIsInstalled ? gitProxy.version() : 'built-in' } async getGitConfig() { @@ -77,13 +61,12 @@ class IsoGitPluginClient extends ElectronBasePluginClient { } } - async status(cmd: any) { + async status(cmd: statusInput) { if (!this.workingDir || this.workingDir === '') { throw new Error('No working directory') } - if (this.workingDir === '') { return [] } @@ -94,30 +77,25 @@ class IsoGitPluginClient extends ElectronBasePluginClient { } const status = await git.statusMatrix({ - ...await this.getGitConfig(), - ...cmd + ...(await this.getGitConfig()), + ...cmd, }) - //console.log('STATUS', status, await this.getGitConfig()) + return status } - async log(cmd: any) { + async log(cmd: logInputType) { - /* we will use isomorphic git for now - if(this.gitIsInstalled){ - const log = await gitProxy.log(this.workingDir, cmd.ref) - console.log('LOG', log) - return log - } - */ + const token = await this.call('config' as any, 'getAppParameter', 'settings/gist-access-token') if (this.workingDir === '') { return [] } const log = await git.log({ - ...await this.getGitConfig(), - ...cmd + ...(await this.getGitConfig()), + ...cmd, + depth: cmd.depth || 10, }) return log @@ -129,62 +107,45 @@ class IsoGitPluginClient extends ElectronBasePluginClient { } const add = await git.add({ - ...await this.getGitConfig(), - ...cmd + ...(await this.getGitConfig()), + ...cmd, }) return add } async rm(cmd: any) { - if (!this.workingDir || this.workingDir === '') { throw new Error('No working directory') } const rm = await git.remove({ - ...await this.getGitConfig(), - ...cmd + ...(await this.getGitConfig()), + ...cmd, }) return rm } - async reset(cmd: any) { - - if (!this.workingDir || this.workingDir === '') { - throw new Error('No working directory') - } - - const reset = await git.resetIndex({ - ...await this.getGitConfig(), - ...cmd - }) - - return reset - } - - - async commit(cmd: any) { + async commit(cmd: commitInputType) { if (!this.workingDir || this.workingDir === '') { throw new Error('No working directory') } if (this.gitIsInstalled) { - const status = await gitProxy.commit(this.workingDir, cmd.message) + const status = await gitProxy.commit(this.workingDir, cmd) return status } const commit = await git.commit({ - ...await this.getGitConfig(), - ...cmd + ...(await this.getGitConfig()), + ...cmd, }) return commit } - async init(input: any) { - + async init(input: initInputType) { if (!this.workingDir || this.workingDir === '') { throw new Error('No working directory') } @@ -193,158 +154,119 @@ class IsoGitPluginClient extends ElectronBasePluginClient { return status } await git.init({ - ...await this.getGitConfig(), - defaultBranch: (input && input.branch) || 'main' + ...(await this.getGitConfig()), + defaultBranch: (input && input.defaultBranch) || 'main', }) } - async branch(cmd: any) { + async branch(cmd: branchInputType) { if (!this.workingDir || this.workingDir === '') { return null } const branch = await git.branch({ - ...await this.getGitConfig(), - ...cmd + ...(await this.getGitConfig()), + ...cmd, }) return branch } - async lsfiles(cmd: any) { - if (!this.workingDir || this.workingDir === '') { - return [] - } - const lsfiles = await git.listFiles({ - ...await this.getGitConfig(), - ...cmd - }) - return lsfiles - } + async resolveref(cmd: resolveRefInput) { - async resolveref(cmd: any) { if (!this.workingDir || this.workingDir === '') { return null } const resolveref = await git.resolveRef({ - ...await this.getGitConfig(), - ...cmd + ...(await this.getGitConfig()), + ...cmd, }) return resolveref } - async readblob(cmd: any) { - if (!this.workingDir || this.workingDir === '') { throw new Error('No working directory') } const readblob = await git.readBlob({ - ...await this.getGitConfig(), - ...cmd + ...(await this.getGitConfig()), + ...cmd, }) return readblob } - async checkout(cmd: any) { + async checkout(cmd: checkoutInputType) { if (!this.workingDir || this.workingDir === '') { throw new Error('No working directory') } - - const checkout = await git.checkout({ - ...await this.getGitConfig(), - ...cmd - }) - - return checkout + if (this.gitIsInstalled) { + return await gitProxy.checkout(this.workingDir, cmd) + } else { + const checkout = await git.checkout({ + ...(await this.getGitConfig()), + ...cmd, + }) + return checkout + } } - async push(cmd: any) { - + async push(input: pushInputType) { if (!this.workingDir || this.workingDir === '') { throw new Error('No working directory') } if (this.gitIsInstalled) { - await gitProxy.push(this.workingDir, cmd.remote, cmd.ref, cmd.remoteRef, cmd.force) - + return await gitProxy.push(this.workingDir, input) } else { - - const push = await git.push({ - ...await this.getGitConfig(), - ...cmd, - ...parseInput(cmd.input) - }) + const push = await isoGit.push(input, await this.getGitConfig(), this) return push } - } - async pull(cmd: any) { + async pull(input: pullInputType) { if (!this.workingDir || this.workingDir === '') { throw new Error('No working directory') } if (this.gitIsInstalled) { - await gitProxy.pull(this.workingDir, cmd.remote, cmd.ref, cmd.remoteRef) - + return await gitProxy.pull(this.workingDir, input) } else { - - const pull = await git.pull({ - ...await this.getGitConfig(), - ...cmd, - ...parseInput(cmd.input) - }) - + const pull = await isoGit.pull(input, await this.getGitConfig(), this) return pull - } } - async fetch(cmd: any) { + async fetch(input: fetchInputType) { if (!this.workingDir || this.workingDir === '') { throw new Error('No working directory') } if (this.gitIsInstalled) { - await gitProxy.fetch(this.workingDir, cmd.remote, cmd.remoteRef) - + await gitProxy.fetch(this.workingDir, input) } else { - - const fetch = await git.fetch({ - ...await this.getGitConfig(), - ...cmd, - ...parseInput(cmd.input) - }) - + const fetch = await isoGit.fetch(input, await this.getGitConfig(), this) return fetch } } - async clone(cmd: any) { - + async clone(cmd: cloneInputType) { if (this.gitIsInstalled) { try { - await gitProxy.clone(cmd.url, cmd.dir) + this.call('terminal' as any, 'log', 'Cloning using git... please wait.') + await gitProxy.clone(cmd) } catch (e) { throw e } } else { try { this.call('terminal' as any, 'log', 'Cloning using builtin git... please wait.') - const clone = await git.clone({ - ...await this.getGitConfig(), - ...cmd, - ...parseInput(cmd.input), - dir: cmd.dir || this.workingDir - }) - + const clone = await isoGit.clone(cmd, await this.getGitConfig(), this) return clone } catch (e) { console.log('CLONE ERROR', e) @@ -353,85 +275,74 @@ class IsoGitPluginClient extends ElectronBasePluginClient { } } - async addremote(cmd: any) { - + async addremote(input: remote) { const addremote = await git.addRemote({ - ...await this.getGitConfig(), - ...cmd + ...(await this.getGitConfig()), + url: input.url, + remote: input.name, }) return addremote } - async delremote(cmd: any) { - + async delremote(input: remote) { const delremote = await git.deleteRemote({ - ...await this.getGitConfig(), - ...cmd + ...(await this.getGitConfig()), + remote: input.name, }) return delremote } + async remotes() { - - remotes = async () => { if (!this.workingDir || this.workingDir === '') { return [] } - let remotes: remote[] = [] - remotes = (await git.listRemotes({ ...await this.getGitConfig() })).map((remote) => { return { name: remote.remote, url: remote.url } } - ) - return remotes + const defaultConfig = await this.getGitConfig() + return await isoGit.remotes(defaultConfig) } - async currentbranch() { - if (!this.workingDir || this.workingDir === '') { - return '' - } - try { - const defaultConfig = await this.getGitConfig() - const name = await git.currentBranch(defaultConfig) + async currentbranch(input: currentBranchInput) { - return name - } catch (e) { + if (!this.workingDir || this.workingDir === '') { return '' } + const defaultConfig = await this.getGitConfig() + return await isoGit.currentbranch(input, defaultConfig) } + async branches(config: any) { - async branches() { if (!this.workingDir || this.workingDir === '') { return [] } - try { - let cmd: any = { ...await this.getGitConfig() } - const remotes = await this.remotes() - let branches = [] - branches = (await git.listBranches(cmd)).map((branch) => { return { remote: undefined, name: branch } }) - for (const remote of remotes) { - cmd = { - ...cmd, - remote: remote.name - } - - const remotebranches = (await git.listBranches(cmd)).map((branch) => { return { remote: remote.name, name: branch } }) - branches = [...branches, ...remotebranches] - - } - return branches - } catch (e) { - return [] - } + const defaultConfig = await this.getGitConfig() + return await isoGit.branches(defaultConfig) } - async startClone() { this.call('filePanel' as any, 'clone') } -} - + async getCommitChanges(commitHash1: string, commitHash2: string): Promise { + return await isoGit.getCommitChanges(commitHash1, commitHash2, await this.getGitConfig()) + } + async compareBranches({branch, remote}: compareBranchesInput): Promise { + return await isoGit.compareBranches({branch, remote}, await this.getGitConfig()) + } + async updateSubmodules(input) { + if (this.gitIsInstalled) { + try { + return await gitProxy.updateSubmodules(this.workingDir) + } catch (e) { + throw e + } + } else { + this.call('terminal', 'log', {type: 'error', value: 'Please install git into your OS to use this functionality...'}) + } + } +} diff --git a/apps/remixdesktop/src/plugins/slitherPlugin.ts b/apps/remixdesktop/src/plugins/slitherPlugin.ts index 5819e0a46b..abf7971e30 100644 --- a/apps/remixdesktop/src/plugins/slitherPlugin.ts +++ b/apps/remixdesktop/src/plugins/slitherPlugin.ts @@ -2,7 +2,22 @@ import { Profile } from "@remixproject/plugin-utils"; import { ElectronBasePlugin, ElectronBasePluginClient } from "@remixproject/plugin-electron" import { ElectronBasePluginRemixdClient } from "../lib/remixd" -import { SlitherClientMixin } from "../lib/slither"; +import * as utils from '../lib/utils' +import { existsSync, readdirSync, readFileSync, unlinkSync } from "fs-extra"; + +export interface OutputStandard { + description: string + title: string + confidence: string + severity: string + sourceMap: any + category?: string + reference?: string + example?: any + [key: string]: any +} + +const { spawn, execSync } = require('child_process') // eslint-disable-line const profile: Profile = { name: 'slither', displayName: 'electron slither', @@ -10,9 +25,9 @@ const profile: Profile = { } export class SlitherPlugin extends ElectronBasePlugin { - clients: any [] + clients: any[] constructor() { - super(profile, clientProfile, SlitherClientMixin(SlitherPluginClient)) + super(profile, clientProfile, SlitherPluginClient) this.methods = [...super.methods] } } @@ -24,10 +39,158 @@ const clientProfile: Profile = { methods: ['analyse'] } - class SlitherPluginClient extends ElectronBasePluginRemixdClient { - constructor(webContentsId: number, profile: Profile) { - super(webContentsId, profile); + + mapNpmDepsDir(list) { + const remixNpmDepsPath = utils.absolutePath('.deps/npm', this.currentSharedFolder) + const localNpmDepsPath = utils.absolutePath('node_modules', this.currentSharedFolder) + const npmDepsExists = existsSync(remixNpmDepsPath) + const nodeModulesExists = existsSync(localNpmDepsPath) + let isLocalDep = false + let isRemixDep = false + let allowPathString = '' + let remapString = '' + + for (const e of list) { + const importPath = e.replace(/import ['"]/g, '').trim() + const packageName = importPath.split('/')[0] + if (nodeModulesExists && readdirSync(localNpmDepsPath).includes(packageName)) { + isLocalDep = true + remapString += `${packageName}=./node_modules/${packageName} ` + } else if (npmDepsExists && readdirSync(remixNpmDepsPath).includes(packageName)) { + isRemixDep = true + remapString += `${packageName}=./.deps/npm/${packageName} ` + } + } + if (isLocalDep) allowPathString += './node_modules,' + if (isRemixDep) allowPathString += './.deps/npm,' + + return { remapString, allowPathString } + } + + transform(detectors: Record[]): OutputStandard[] { + const standardReport: OutputStandard[] = [] + for (const e of detectors) { + const obj = {} as OutputStandard + obj.description = e.description + obj.title = e.check + obj.confidence = e.confidence + obj.severity = e.impact + obj.sourceMap = e.elements.map((element) => { + delete element.source_mapping.filename_used + delete element.source_mapping.filename_absolute + return element + }) + standardReport.push(obj) + } + return standardReport + } + + analyse(filePath: string, compilerConfig: Record) { + return new Promise((resolve, reject) => { + const options = { cwd: this.currentSharedFolder, shell: true } + + const { currentVersion, optimize, evmVersion } = compilerConfig + if (currentVersion && currentVersion.includes('+commit')) { + // Get compiler version with commit id e.g: 0.8.2+commit.661d110 + const versionString: string = currentVersion.substring(0, currentVersion.indexOf('+commit') + 16) + this.log(`[Slither Analysis]: Compiler version is ${versionString}`) + let solcOutput: Buffer + // Check solc current installed version + try { + solcOutput = execSync('solc --version', options) + } catch (err) { + this.error(err) + reject(new Error('Error in running solc command')) + } + if (!solcOutput.toString().includes(versionString)) { + this.log('[Slither Analysis]: Compiler version is different from installed solc version') + // Get compiler version without commit id e.g: 0.8.2 + const version: string = versionString.substring(0, versionString.indexOf('+commit')) + // List solc versions installed using solc-select + try { + const solcSelectInstalledVersions: Buffer = execSync('solc-select versions', options) + // Check if required version is already installed + if (!solcSelectInstalledVersions.toString().includes(version)) { + this.log(`[Slither Analysis]: Installing ${version} using solc-select`) + // Install required version + execSync(`solc-select install ${version}`, options) + } + this.log(`[Slither Analysis]: Setting ${version} as current solc version using solc-select`) + // Set solc current version as required version + execSync(`solc-select use ${version}`, options) + } catch (err) { + this.error(err) + reject(new Error('Error in running solc-select command')) + } + } else this.log('[Slither Analysis]: Compiler version is same as installed solc version') + } + // Allow paths and set solc remapping for import URLs + const fileContent = readFileSync(utils.absolutePath(filePath, this.currentSharedFolder), 'utf8') + const importsArr = fileContent.match(/import ['"][^.|..](.+?)['"];/g) + let remaps = '' + if (importsArr?.length) { + const { remapString } = this.mapNpmDepsDir(importsArr) + remaps = remapString.trim() + } + const optimizeOption: string = optimize ? '--optimize' : '' + const evmOption: string = evmVersion ? `--evm-version ${evmVersion}` : '' + let solcArgs = '' + if (optimizeOption) { + solcArgs += optimizeOption + ' ' + } + if (evmOption) { + if (!solcArgs.endsWith(' ')) solcArgs += ' ' + solcArgs += evmOption + } + if (solcArgs) { + solcArgs = `--solc-args "${solcArgs.trimStart()}"` + } + const solcRemaps = remaps ? `--solc-remaps "${remaps}"` : '' + + const outputFile = 'remix-slither-report.json' + try { + // We don't keep the previous analysis + const outputFilePath = utils.absolutePath(outputFile, this.currentSharedFolder) + if (existsSync(outputFilePath)) unlinkSync(outputFilePath) + } catch (e) { + this.error('unable to remove the output file') + this.error(e.message) + } + const cmd = `slither ${filePath} ${solcArgs} ${solcRemaps} --json ${outputFile}` + this.log('[Slither Analysis]: Running Slither...') + // Added `stdio: 'ignore'` as for contract with NPM imports analysis which is exported in 'stderr' + // get too big and hangs the process. We process analysis from the report file only + const child = spawn(cmd, { cwd: this.currentSharedFolder, shell: true, stdio: 'ignore' }) + + const response = {} + child.on('close', () => { + const outputFileAbsPath: string = utils.absolutePath(outputFile, this.currentSharedFolder) + // Check if slither report file exists + if (existsSync(outputFileAbsPath)) { + let report = readFileSync(outputFileAbsPath, 'utf8') + report = JSON.parse(report) + if (report['success']) { + response['status'] = true + if (!report['results'] || !report['results'].detectors || !report['results'].detectors.length) { + response['count'] = 0 + } else { + const { detectors } = report['results'] + response['count'] = detectors.length + response['data'] = this.transform(detectors) + } + + resolve(response) + } else { + this.log(report['error']) + reject(new Error('Error in running Slither Analysis.')) + } + } else { + this.error('Error in generating Slither Analysis Report. Make sure Slither is properly installed.') + reject(new Error('Error in generating Slither Analysis Report. Make sure Slither is properly installed.')) + } + }) + }) } } diff --git a/apps/remixdesktop/src/plugins/xtermPlugin.ts b/apps/remixdesktop/src/plugins/xtermPlugin.ts index 8bbfdf629b..6c8f16ca28 100644 --- a/apps/remixdesktop/src/plugins/xtermPlugin.ts +++ b/apps/remixdesktop/src/plugins/xtermPlugin.ts @@ -1,32 +1,29 @@ -import { PluginClient } from '@remixproject/plugin' -import { Profile } from '@remixproject/plugin-utils' -import { - ElectronBasePlugin, - ElectronBasePluginClient, -} from '@remixproject/plugin-electron' +import {PluginClient} from '@remixproject/plugin' +import {Profile} from '@remixproject/plugin-utils' +import {ElectronBasePlugin, ElectronBasePluginClient} from '@remixproject/plugin-electron' import os from 'os' import * as pty from 'node-pty' import process from 'node:process' -import { userInfo } from 'node:os' -import { findExecutable } from '../utils/findExecutable' -import { spawnSync } from 'child_process' -import { stripAnsi } from '../lib' -import { DataBatcher } from '../lib/databatcher' +import {userInfo} from 'node:os' +import {findExecutable} from '../utils/findExecutable' +import {exec, spawnSync} from 'child_process' +import {stripAnsi} from '../lib' +import {DataBatcher} from '../lib/databatcher' export const detectDefaultShell = () => { - const { env } = process + const {env} = process if (process.platform === 'win32') { return env.SHELL || 'powershell.exe' } try { - const { shell } = userInfo() + const {shell} = userInfo() if (shell) { return shell } - } catch { } + } catch {} if (process.platform === 'darwin') { return env.SHELL || '/bin/zsh' @@ -38,10 +35,7 @@ export const detectDefaultShell = () => { // Stores default shell when imported. const defaultShell = detectDefaultShell() -const getShellEnvArgs = [ - '-ilc', - 'echo -n "_SHELL_ENV_DELIMITER_"; env; echo -n "_SHELL_ENV_DELIMITER_"; exit', -] +const getShellEnvArgs = ['-ilc', 'echo -n "_SHELL_ENV_DELIMITER_"; env; echo -n "_SHELL_ENV_DELIMITER_"; exit'] const getShellEnvEnv = { // Disables Oh My Zsh auto-update thing that can block the process. @@ -117,9 +111,9 @@ class XtermPluginClient extends ElectronBasePluginClient { this.workingDir = await this.call('fs' as any, 'getWorkingDir') console.log('workingDir', this.workingDir) }) - + if (!(process.platform === 'win32')) { - const { stdout } = spawnSync(defaultShell, getShellEnvArgs, { + const {stdout} = spawnSync(defaultShell, getShellEnvArgs, { encoding: 'utf8', }) this.parsedEnv = parseEnv(stdout) @@ -149,7 +143,6 @@ class XtermPluginClient extends ElectronBasePluginClient { async createTerminal(path?: string, shell?: string): Promise { const start_time = Date.now() console.log('createTerminal', path, shell || defaultShell) - const env = this.parsedEnv || process.env @@ -160,11 +153,10 @@ class XtermPluginClient extends ElectronBasePluginClient { cwd: path || this.workingDir || process.cwd(), env: env, encoding: 'utf8', - }); + }) const dataBatcher = new DataBatcher(ptyProcess.pid) this.dataBatchers[ptyProcess.pid] = dataBatcher ptyProcess.onData((data: string) => { - //console.log('data', data) dataBatcher.write(Buffer.from(data)) }) ptyProcess.onExit(() => { @@ -181,27 +173,48 @@ class XtermPluginClient extends ElectronBasePluginClient { } async closeTerminal(pid: number): Promise { - if (this.terminals) { - if (this.terminals[pid]) { - try { - this.terminals[pid].kill() - } catch (err) { - // ignore + console.log('closeTerminal', pid) + + try { + if (this.terminals) { + + if (this.dataBatchers[pid]) delete this.dataBatchers[pid] + + if (this.terminals[pid]) { + try { + if (os.platform() === 'win32') { + // For Windows, use taskkill to terminate the process + exec(`taskkill /PID ${pid} /T /F`, (error, stdout, stderr) => { + if (error) { + console.error(`Error killing process: ${error}`); + }else{ + console.log(`stdout: ${stdout}`); + console.error(`stderr: ${stderr}`); + } + }); + } else { + this.terminals[pid].kill(); + } + } catch (err) { + console.error(err) + // ignore + } + delete this.terminals[pid] } - delete this.terminals[pid] } - if (this.dataBatchers[pid]) - delete this.dataBatchers[pid] + this.emit('close', pid) + } catch (err) { + console.error(err) } - this.emit('close', pid) + } - async resize({ cols, rows }: { cols: number; rows: number }, pid: number) { + async resize({cols, rows}: {cols: number; rows: number}, pid: number) { if (this.terminals[pid]) { try { this.terminals[pid].resize(cols, rows) } catch (_err) { - const err = _err as { stack: any } + const err = _err as {stack: any} console.error(err.stack) } } else { diff --git a/apps/remixdesktop/src/tools/git.ts b/apps/remixdesktop/src/tools/git.ts index 841ba952b0..ed28a70b82 100644 --- a/apps/remixdesktop/src/tools/git.ts +++ b/apps/remixdesktop/src/tools/git.ts @@ -1,6 +1,7 @@ import { exec } from 'child_process'; import { CommitObject, ReadCommitResult } from 'isomorphic-git'; import { promisify } from 'util'; +import { cloneInputType, commitInputType, fetchInputType, pullInputType, pushInputType, checkoutInputType } from "@remix-api"; const execAsync = promisify(exec); const statusTransFormMatrix = (status: string) => { @@ -9,12 +10,16 @@ const statusTransFormMatrix = (status: string) => { return [0, 2, 0] case 'A ': return [0, 2, 2] + case 'R ': + return [0, 2, 2] case 'M ': return [1, 2, 2] case 'MM': return [1, 2, 3] case ' M': - return [1, 2, 0] + return [1, 2, 1] + case 'AD': + return [0, 0, 3] case ' D': return [1, 0, 1] case 'D ': @@ -37,34 +42,87 @@ export const gitProxy = { } }, + async defaultRemoteName(path: string) { + try { + const { stdout } = await execAsync('git remote', { cwd: path }); + const remotes = stdout.trim().split('\n'); + return remotes[0]; + } catch (error) { + throw new Error(`Failed to get the default remote name: ${error.message}`); + } + }, - clone: async (url: string, path: string) => { - const { stdout, stderr } = await execAsync(`git clone ${url} "${path}"`); + clone: async (input: cloneInputType) => { + const { stdout, stderr } = await execAsync(`git clone ${input.url} "${input.dir}"`); }, - async push(path: string, remote: string, src: string, branch: string, force: boolean = false) { - const { stdout, stderr } = await execAsync(`git push ${force ? ' -f' : ''} ${remote} ${src}:${branch}`, { cwd: path }); + async push(path: string, input: pushInputType) { + if(!input.remote || !input.remote.name) { + input.remote = { name: await gitProxy.defaultRemoteName(path), url: '' } + } + let remoteRefString = '' + if(input.remoteRef && !input.remoteRef.name) { + remoteRefString = `:${input.remoteRef.name}` + } + const { stdout, stderr } = await execAsync(`git push ${input.force ? ' -f' : ''} ${input.remote.name}${remoteRefString} ${input.ref.name}`, { cwd: path }); }, - async pull(path: string, remote: string, src: string, branch: string) { - const { stdout, stderr } = await execAsync(`git pull ${remote} ${src}:${branch}`, { cwd: path }); + async pull(path: string, input: pullInputType) { + if(!input.remote || !input.remote.name) { + input.remote = { name: await gitProxy.defaultRemoteName(path), url: '' } + } + let remoteRefString = '' + if(input.remoteRef && !input.remoteRef.name) { + remoteRefString = `:${input.remoteRef.name}` + } + const { stdout, stderr } = await execAsync(`git pull ${input.remote.name} ${input.ref.name}${remoteRefString}`, { cwd: path }); }, - async fetch(path: string, remote: string, branch: string) { - const { stdout, stderr } = await execAsync(`git fetch ${remote} ${branch}`, { cwd: path }); + async fetch(path: string, input: fetchInputType) { + if(!input.remote || !input.remote.name) { + input.remote = { name: await gitProxy.defaultRemoteName(path), url: '' } + } + + try { + const { stdout, stderr } = await execAsync(`git fetch ${input.remote.name} ${(input.ref && input.ref.name) ? input.ref.name : ''}`, { cwd: path }); + if (stdout) { + console.log('stdout:', stdout); + } + if (stderr) { + console.error('stderr:', stderr); + } + } catch (error) { + console.error('Error during fetch:', error); + } + }, + + async checkout(path: string, input: checkoutInputType) { + let force = input.force ? ' -f' : ''; + const { stdout, stderr } = await execAsync(`git checkout ${force} ${input.ref}`, { cwd: path }); }, - async commit(path: string, message: string) { + async commit(path: string, input: commitInputType) { - await execAsync(`git commit -m '${message}'`, { cwd: path }); + await execAsync(`git commit -m '${input.message}'`, { cwd: path }); const { stdout, stderr } = await execAsync(`git rev-parse HEAD`, { cwd: path }); + console.log('stdout commit:', stdout); return stdout; }, async init(path: string) { - await execAsync(`git init`, { cwd: path }); + await execAsync(`git init --initial-branch=main`, { cwd: path }); + }, + + async updateSubmodules(path: string) { + const { stdout, stderr } = await execAsync(`git submodule update --init --recursive`, { cwd: path }); + if (stdout) { + console.log('stdout:', stdout); + } + if (stderr) { + console.error('stderr:', stderr); + } }, @@ -103,7 +161,7 @@ export const gitProxy = { return 0 }) - + console.log('files', files) return files }, diff --git a/apps/remixdesktop/test/nighwatch.app.ts b/apps/remixdesktop/test/nighwatch.app.ts index 2583c7e58f..77ff0f9b7f 100644 --- a/apps/remixdesktop/test/nighwatch.app.ts +++ b/apps/remixdesktop/test/nighwatch.app.ts @@ -3,8 +3,8 @@ import fs from 'fs'; -const useIsoGit = process.argv.includes('--useIsoGit'); -const useOffline = process.argv.includes('--useOffline'); +const useIsoGit = process.argv.includes('--use-isogit'); +const useOffline = process.argv.includes('--use-offline'); // Function to read JSON file synchronously function readJSONFileSync(filename: string): any { @@ -71,12 +71,12 @@ module.exports = { // Check if running on CircleCI or locally let args = process.env.CIRCLECI ? ["--e2e"] : ["--e2e-local"]; - if(useIsoGit) args = [...args, '--useIsoGit']; - if(useOffline) args = [...args, '--useOffline']; + if(useIsoGit) args = [...args, '--use-isogit']; + if(useOffline) args = [...args, '--use-offline']; // Set display size - const windowSize = "--window-size=1920,1080"; - args = [...args, windowSize]; + const windowSize = "--window-size=1000,1000"; + args = [...args]; switch (type) { case 'Windows_NT': @@ -92,6 +92,7 @@ module.exports = { break; } + console.log('binaryPath', binaryPath); return { binary: binaryPath, args: args diff --git a/apps/remixdesktop/test/tests/app/gist.test.ts b/apps/remixdesktop/test/tests/app/gist.test.ts index bbbb710ff7..b53c741910 100644 --- a/apps/remixdesktop/test/tests/app/gist.test.ts +++ b/apps/remixdesktop/test/tests/app/gist.test.ts @@ -5,7 +5,9 @@ const tests = { before: function (browser: NightwatchBrowser, done: VoidFunction) { done() }, - 'start gist': !function (browser: NightwatchBrowser) { + 'start gist': function (browser: NightwatchBrowser) { + browser.end() + /* browser .waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000) .waitForElementVisible('*[data-id="landingPageImportFromGist"]') @@ -25,6 +27,7 @@ const tests = { .click('[data-id="treeViewLitreeViewItemcontracts"]') .openFile('contracts/3_Ballot.sol') .end() + */ } } diff --git a/apps/remixdesktop/test/tests/app/offline.test.ts b/apps/remixdesktop/test/tests/app/offline.test.ts index 040e587e5e..284d44991a 100644 --- a/apps/remixdesktop/test/tests/app/offline.test.ts +++ b/apps/remixdesktop/test/tests/app/offline.test.ts @@ -11,9 +11,11 @@ module.exports = { .waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000) .waitForElementVisible('button[data-id="landingPageImportFromTemplate"]') .click('button[data-id="landingPageImportFromTemplate"]') + .waitForElementPresent('*[data-id="create-remixDefault"]') + .scrollAndClick('*[data-id="create-remixDefault"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') - .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') - .click('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') + .waitForElementPresent('[data-id="TemplatesSelectionModalDialogContainer-react"] .modal-ok') + .click('[data-id="TemplatesSelectionModalDialogContainer-react"] .modal-ok') .pause(3000) .windowHandles(function (result) { console.log(result.value)