Merge branch 'master' of https://github.com/ethereum/remix-project into editorcontext

editorcontextDummy
filip mertens 2 years ago
commit 90cbfee082
  1. 44
      .circleci/config.yml
  2. 6
      .github/workflows/publish-action.yml
  3. 49
      README.md
  4. 4
      apps/remix-ide-e2e/src/select_tests.sh
  5. 2
      apps/remix-ide-e2e/src/tests/compiler_api.test.ts
  6. 2
      apps/remix-ide-e2e/src/tests/fileManager_api.test.ts
  7. 22
      apps/remix-ide-e2e/src/tests/plugin_api.ts
  8. 2
      apps/remix-ide-e2e/src/tests/recorder.test.ts
  9. 2
      apps/remix-ide-e2e/src/tests/url.test.ts
  10. 112
      apps/remix-ide-e2e/src/tests/workspace.test.ts
  11. 4
      apps/remix-ide/.travis.yml
  12. 44
      apps/remix-ide/README.md
  13. 8
      apps/remix-ide/ci/browser_test.sh
  14. 6
      apps/remix-ide/ci/browser_tests.sh
  15. 6
      apps/remix-ide/ci/browser_tests_plugin_api.sh
  16. 8
      apps/remix-ide/ci/flaky.sh
  17. 2
      apps/remix-ide/ci/lint.sh
  18. 4
      apps/remix-ide/docs/locations.md
  19. 5
      apps/remix-ide/docs/remixd.md
  20. 6
      apps/remix-ide/release-process.md
  21. BIN
      apps/remix-ide/remix-screenshot-400h.png
  22. BIN
      apps/remix-ide/remix_screenshot.png
  23. 20
      apps/remix-ide/src/app/panels/tab-proxy.js
  24. 2
      apps/remix-ide/src/app/plugins/config.ts
  25. 2
      apps/remix-ide/src/app/tabs/ganache-provider.tsx
  26. 5
      apps/remix-ide/src/remixAppManager.js
  27. 6
      apps/solidity-compiler/src/app/compiler-api.ts
  28. 27
      apps/solidity-compiler/src/app/compiler.ts
  29. 2
      libs/remix-analyzer/README.md
  30. 2
      libs/remix-astwalker/README.md
  31. 2
      libs/remix-debug/README.md
  32. 2
      libs/remix-lib/README.md
  33. 2
      libs/remix-lib/src/types/ICompilerApi.ts
  34. 2
      libs/remix-simulator/README.md
  35. 2
      libs/remix-solidity/README.md
  36. 6
      libs/remix-solidity/src/compiler/compiler-input.ts
  37. 42
      libs/remix-solidity/src/compiler/compiler.ts
  38. 2
      libs/remix-solidity/src/compiler/types.ts
  39. 4
      libs/remix-tests/README.md
  40. 2
      libs/remix-tests/tests/testRunner.cli.spec.ts
  41. 22
      libs/remix-ui/editor/src/lib/remix-ui-editor.tsx
  42. 1
      libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx
  43. 6
      libs/remix-ui/run-tab/src/lib/components/instanceContainerUI.tsx
  44. 51
      libs/remix-ui/run-tab/src/lib/components/recorderCardUI.tsx
  45. 7
      libs/remix-ui/run-tab/src/lib/css/card.css
  46. 15
      libs/remix-ui/run-tab/src/lib/css/run-tab.css
  47. 3
      libs/remix-ui/run-tab/src/lib/types/index.ts
  48. 218
      libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx
  49. 18
      libs/remix-ui/solidity-compiler/src/lib/compilerConfiguration.tsx
  50. 9
      libs/remix-ui/solidity-compiler/src/lib/css/style.css
  51. 16
      libs/remix-ui/solidity-compiler/src/lib/logic/compileTabLogic.ts
  52. 18
      libs/remix-ui/solidity-compiler/src/lib/solidity-compiler.tsx
  53. 2
      libs/remix-ui/solidity-compiler/src/lib/types/index.ts
  54. 2
      libs/remix-ui/solidity-compiler/tsconfig.json
  55. 2
      libs/remix-ui/tabs/src/lib/remix-ui-tabs.tsx
  56. 2
      libs/remix-ui/tree-view/src/lib/remix-ui-tree-view.tsx
  57. 2
      libs/remix-ui/workspace/src/lib/components/file-label.tsx
  58. 5
      libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
  59. 2
      libs/remix-url-resolver/README.md
  60. 2
      libs/remix-ws-templates/README.md
  61. 4
      libs/remix-ws-templates/src/index.ts
  62. 8
      libs/remix-ws-templates/src/templates/ozerc20/index.ts
  63. 2
      libs/remix-ws-templates/src/templates/ozerc20/scripts/ethers-lib.ts
  64. 2
      libs/remix-ws-templates/src/templates/ozerc20/scripts/web3-lib.ts
  65. 14
      libs/remix-ws-templates/src/templates/ozerc721/contracts/SampleERC721.sol
  66. 16
      libs/remix-ws-templates/src/templates/ozerc721/index.ts
  67. 10
      libs/remix-ws-templates/src/templates/ozerc721/scripts/deploy_with_ethers.ts
  68. 10
      libs/remix-ws-templates/src/templates/ozerc721/scripts/deploy_with_web3.ts
  69. 26
      libs/remix-ws-templates/src/templates/ozerc721/scripts/ethers-lib.ts
  70. 27
      libs/remix-ws-templates/src/templates/ozerc721/scripts/web3-lib.ts
  71. 18
      libs/remix-ws-templates/src/templates/ozerc721/tests/SampleERC721_test.sol
  72. 10
      libs/remix-ws-templates/src/templates/remixDefault/index.ts
  73. 31
      libs/remix-ws-templates/src/templates/zeroxErc20/contracts/SampleERC20.sol
  74. 16
      libs/remix-ws-templates/src/templates/zeroxErc20/index.ts
  75. 10
      libs/remix-ws-templates/src/templates/zeroxErc20/scripts/deploy_with_ethers.ts
  76. 10
      libs/remix-ws-templates/src/templates/zeroxErc20/scripts/deploy_with_web3.ts
  77. 26
      libs/remix-ws-templates/src/templates/zeroxErc20/scripts/ethers-lib.ts
  78. 27
      libs/remix-ws-templates/src/templates/zeroxErc20/scripts/web3-lib.ts
  79. 18
      libs/remix-ws-templates/src/templates/zeroxErc20/tests/SampleERC20_test.sol
  80. 4
      libs/remixd/README.md
  81. 2
      libs/remixd/nodemon.json
  82. 2
      libs/remixd/src/bin/remixd.ts
  83. 48108
      package-lock.json
  84. 82
      package.json
  85. 36
      release-management.md
  86. 2
      release-process.md
  87. 24426
      yarn.lock

@ -30,16 +30,16 @@ jobs:
- restore_cache: - restore_cache:
keys: keys:
- v1-deps-{{ checksum "package-lock.json" }} - v1-deps-{{ checksum "package-lock.json" }}
- run: npm install - run: yarn install
- save_cache: - save_cache:
key: v1-deps-{{ checksum "package-lock.json" }} key: v1-deps-{{ checksum "package-lock.json" }}
paths: paths:
- node_modules - node_modules
- run: npm run downloadsolc_assets - run: yarn run downloadsolc_assets
- run: npx nx build remix-ide - run: npx nx build remix-ide
- run: npx nx build remix-ide-e2e-src-local-plugin - run: npx nx build remix-ide-e2e-src-local-plugin
- run: npm run build:libs - run: yarn run build:libs
- run: mkdir persist && zip -r persist/dist.zip dist - run: mkdir persist && zip -r persist/dist.zip dist
- persist_to_workspace: - persist_to_workspace:
root: . root: .
@ -65,7 +65,7 @@ jobs:
- restore_cache: - restore_cache:
keys: keys:
- v1-deps-{{ checksum "package-lock.json" }} - v1-deps-{{ checksum "package-lock.json" }}
- run: npm install - run: yarn install
- run: - run:
name: Remix Libs Linting name: Remix Libs Linting
command: ./apps/remix-ide/ci/lint.sh command: ./apps/remix-ide/ci/lint.sh
@ -92,9 +92,9 @@ jobs:
- restore_cache: - restore_cache:
keys: keys:
- v1-deps-{{ checksum "package-lock.json" }} - v1-deps-{{ checksum "package-lock.json" }}
- run: npm i - run: yarn install
- run: cd dist/libs/remix-tests && npm install - run: cd dist/libs/remix-tests && yarn install
- run: npm run test:libs - run: yarn run test:libs
remix-ide-chrome: remix-ide-chrome:
docker: docker:
@ -128,7 +128,7 @@ jobs:
- restore_cache: - restore_cache:
keys: keys:
- v1-deps-{{ checksum "package-lock.json" }} - v1-deps-{{ checksum "package-lock.json" }}
- run: npm install - run: yarn install
- run: - run:
name: Start Selenium name: Start Selenium
command: java -jar /usr/local/bin/selenium.jar command: java -jar /usr/local/bin/selenium.jar
@ -171,7 +171,7 @@ jobs:
- restore_cache: - restore_cache:
keys: keys:
- v1-deps-{{ checksum "package-lock.json" }} - v1-deps-{{ checksum "package-lock.json" }}
- run: npm install - run: yarn install
- run: - run:
name: Start Selenium name: Start Selenium
command: java -jar /usr/local/bin/selenium.jar command: java -jar /usr/local/bin/selenium.jar
@ -214,7 +214,7 @@ jobs:
- restore_cache: - restore_cache:
keys: keys:
- v1-deps-{{ checksum "package-lock.json" }} - v1-deps-{{ checksum "package-lock.json" }}
- run: npm install - run: yarn install
- run: - run:
name: Start Selenium name: Start Selenium
command: java -jar /usr/local/bin/selenium.jar command: java -jar /usr/local/bin/selenium.jar
@ -256,7 +256,7 @@ jobs:
- restore_cache: - restore_cache:
keys: keys:
- v1-deps-{{ checksum "package-lock.json" }} - v1-deps-{{ checksum "package-lock.json" }}
- run: npm install - run: yarn install
- run: - run:
name: Start Selenium name: Start Selenium
command: java -jar /usr/local/bin/selenium.jar command: java -jar /usr/local/bin/selenium.jar
@ -299,7 +299,7 @@ jobs:
- restore_cache: - restore_cache:
keys: keys:
- v1-deps-{{ checksum "package-lock.json" }} - v1-deps-{{ checksum "package-lock.json" }}
- run: npm install - run: yarn install
- run: - run:
name: Start Selenium name: Start Selenium
command: java -jar /usr/local/bin/selenium.jar command: java -jar /usr/local/bin/selenium.jar
@ -328,9 +328,9 @@ jobs:
steps: steps:
- checkout - checkout
- run: npm install - run: yarn install
- run: npm run downloadsolc_assets - run: yarn run downloadsolc_assets
- run: npm run build:production - run: yarn run build:production
- run: - run:
name: Deploy name: Deploy
command: | command: |
@ -357,9 +357,9 @@ jobs:
steps: steps:
- checkout - checkout
- run: npm install - run: yarn install
- run: npm run downloadsolc_assets - run: yarn run downloadsolc_assets
- run: npm run build:production - run: yarn run build:production
- run: - run:
name: Deploy name: Deploy
command: | command: |
@ -385,10 +385,10 @@ jobs:
steps: steps:
- checkout - checkout
- run: npm install - run: yarn install
- run: npm run build:libs - run: yarn run build:libs
- run: npm run downloadsolc_assets - run: yarn run downloadsolc_assets
- run: npm run build:production - run: yarn run build:production
- run: - run:
name: Deploy name: Deploy
command: | command: |

@ -9,11 +9,11 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
- run: npm install - run: yarn install
- run: ls - run: ls
- run: pwd - run: pwd
- run: npm run downloadsolc_assets - run: yarn run downloadsolc_assets
- run: npm run build:production - run: yarn run build:production
- run: echo "action_state=$('./apps/remix-ide/ci/publishIpfs')" >> $GITHUB_ENV - run: echo "action_state=$('./apps/remix-ide/ci/publishIpfs')" >> $GITHUB_ENV
- uses: mshick/add-pr-comment@v1 - uses: mshick/add-pr-comment@v1
with: with:

@ -8,18 +8,23 @@
[![Twitter Follow](https://img.shields.io/twitter/follow/ethereumremix?style=social)](https://twitter.com/ethereumremix) [![Twitter Follow](https://img.shields.io/twitter/follow/ethereumremix?style=social)](https://twitter.com/ethereumremix)
# Remix Project # Remix Project
**Remix Project** is a rich toolset including Remix IDE, a comprehensive smart contract development tool. The Remix Project also includes Remix Plugin Engine and Remix Libraries which are low-level tools for wider use.
**Remix Project** is a platform for development tools that use a plugin architecture. It encompasses sub-projects including Remix Plugin Engine, Remix Libraries, and of course Remix IDE. ## Remix IDE
**Remix IDE** is used for the entire journey of contract development by users of any knowledge level. It fosters a fast development cycle and has a rich set of plugins with intuitive GUIs. The IDE comes in 2 flavors and a VSCode extension:
**Remix IDE** is an open source web and desktop application. It fosters a fast development cycle and has a rich set of plugins with intuitive GUIs. Remix is used for the **entire journey of contract development with [Solidity language](https://soliditylang.org/)** as well as a playground for learning and teaching [Ethereum](https://ethereum.org/). **Remix Online IDE**, see: [https://remix.ethereum.org](https://remix.ethereum.org)
Start developing using Remix on browser, visit: [https://remix.ethereum.org](https://remix.ethereum.org) :point_right: Supported browsers: Firefox v100.0.1 & Chrome v101.0.4951.64. No support for Remix's use on tablets or smartphones or telephones.
For desktop version, see releases: [https://github.com/ethereum/remix-desktop/releases](https://github.com/ethereum/remix-desktop/releases) **Remix Desktop IDE**, see releases: [https://github.com/ethereum/remix-desktop/releases](https://github.com/ethereum/remix-desktop/releases)
![Remix screenshot](https://github.com/ethereum/remix-project/raw/master/apps/remix-ide/remix_screenshot.png) ![Remix screenshot](https://github.com/ethereum/remix-project/raw/master/apps/remix-ide/remix-screenshot-400h.png)
:point_right: **Remix libraries** work as a core of native plugins of Remix IDE. Read more about libraries [here](libs/README.md) **VSCode extension**, see: [Ethereum-Remix](https://marketplace.visualstudio.com/items?itemName=RemixProject.ethereum-remix)
## Remix libraries
Remix libraries are essential for Remix IDE's native plugins. Read more about libraries [here](libs/README.md)
## Offline Usage ## Offline Usage
@ -30,7 +35,7 @@ Note: It contains the latest supported version of Solidity available at the time
## Setup ## Setup
* Install **NPM** and **Node.js**. See [Guide](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) <br/> * Install **Yarn** and **Node.js**. See [Guide for NodeJs](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) and [Yarn install](https://classic.yarnpkg.com/lang/en/docs/install)<br/>
*Supported versions:* *Supported versions:*
```bash ```bash
"engines": { "engines": {
@ -40,7 +45,7 @@ Note: It contains the latest supported version of Solidity available at the time
``` ```
* Install [Nx CLI](https://nx.dev/react/cli/overview) globally to enable running **nx executable commands**. * Install [Nx CLI](https://nx.dev/react/cli/overview) globally to enable running **nx executable commands**.
```bash ```bash
npm install -g @nrwl/cli yarn global add @nrwl/cli
``` ```
* Clone the github repository (`wget` need to be installed first): * Clone the github repository (`wget` need to be installed first):
@ -50,8 +55,8 @@ git clone https://github.com/ethereum/remix-project.git
* Build `remix-project`: * Build `remix-project`:
```bash ```bash
cd remix-project cd remix-project
npm install yarn install
npm run build:libs // Build remix libs yarn run build:libs // Build remix libs
nx build nx build
nx serve nx serve
``` ```
@ -63,12 +68,12 @@ Go to your `text editor` and start developing. Browser will automatically refres
## Production Build ## Production Build
To generate react production builds for remix-project. To generate react production builds for remix-project.
```bash ```bash
npm run build:production yarn run build:production
``` ```
Build can be found in `remix-project/dist/apps/remix-ide` directory. Build can be found in `remix-project/dist/apps/remix-ide` directory.
```bash ```bash
npm run serve:production yarn run serve:production
``` ```
Production build will be served by default to `http://localhost:8080/` or `http://127.0.0.1:8080/` Production build will be served by default to `http://localhost:8080/` or `http://127.0.0.1:8080/`
@ -133,17 +138,17 @@ For example, to run unit tests of `remix-analyzer`, use `nx test remix-analyzer`
To run the Selenium tests via Nightwatch: To run the Selenium tests via Nightwatch:
- Install Selenium for first time: `npm run selenium-install` - Install Selenium for first time: `yarn run selenium-install`
- Run a selenium server: `npm run selenium` - Run a selenium server: `yarn run selenium`
- Build & Serve Remix: `nx serve` - Build & Serve Remix: `nx serve`
- Run all the end-to-end tests: - Run all the end-to-end tests:
for Firefox: `npm run nightwatch_local_firefox`, or for Firefox: `yarn run nightwatch_local_firefox`, or
for Google Chrome: `npm run nightwatch_local_chrome` for Google Chrome: `yarn run nightwatch_local_chrome`
- Run a specific test case instead, use a command like this: - Run a specific test case instead, use a command like this:
- npm run nightwatch_local_ballot - yarn run nightwatch_local_ballot
The package.json file contains a list of all the tests you can run. The package.json file contains a list of all the tests you can run.
@ -163,7 +168,7 @@ To run the Selenium tests via Nightwatch:
There is a script to allow selecting the browser and a specific test to run: There is a script to allow selecting the browser and a specific test to run:
``` ```
npm run select_test yarn run select_test
``` ```
You need to have You need to have
@ -209,13 +214,13 @@ module.exports = {
- change package json to locally run all group tests: - change package json to locally run all group tests:
``` ```
"nightwatch_local_debugger": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/debugger_*.spec.js --env=chrome", "nightwatch_local_debugger": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/debugger_*.spec.js --env=chrome",
``` ```
- run the build script to build the test files if you want to run the locally - run the build script to build the test files if you want to run the locally
``` ```
npm run build:e2e yarn run build:e2e
``` ```
### Locally testing group tests ### Locally testing group tests
@ -229,12 +234,12 @@ You can tag any test with a groupname, for example, #group10 and easily run the
This script will give you an option menu, just select the test you want This script will give you an option menu, just select the test you want
``` ```
npm run select_test yarn run select_test
``` ```
#### method 2 #### method 2
``` ```
npm run group_test --test=debugger --group=10 --env=chromeDesktop yarn run group_test --test=debugger --group=10 --env=chromeDesktop
``` ```
- specify chromeDesktop to see the browser action, use 'chrome' to run it headless - specify chromeDesktop to see the browser action, use 'chrome' to run it headless

@ -24,7 +24,7 @@ do
*) echo "invalid option $REPLY";; *) echo "invalid option $REPLY";;
esac esac
done done
npm run build:e2e yarn run build:e2e
PS3='Select a test or command: ' PS3='Select a test or command: '
TESTFILES=( $(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "\.spec\|\.test\|plugin_api" | sort ) ) TESTFILES=( $(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "\.spec\|\.test\|plugin_api" | sort ) )
@ -42,6 +42,6 @@ do
done done
else else
# run the selected test # run the selected test
npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js $opt --env=$BROWSER yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js $opt --env=$BROWSER
fi fi
done done

@ -46,7 +46,7 @@ module.exports = {
browser browser
.addFile('test_updateConfiguration.js', { content: updateConfiguration }) .addFile('test_updateConfiguration.js', { content: updateConfiguration })
.executeScript('remix.exeCurrent()') .executeScript('remix.exeCurrent()')
.pause(5000) .pause(15000)
.addFile('test_updateConfiguration.sol', { content: simpleContract }) .addFile('test_updateConfiguration.sol', { content: simpleContract })
.verifyContracts(['StorageTestUpdateConfiguration'], { wait: 5000, version: '0.6.8+commit.0bbfe453' }) .verifyContracts(['StorageTestUpdateConfiguration'], { wait: 5000, version: '0.6.8+commit.0bbfe453' })
}, },

@ -71,7 +71,7 @@ module.exports = {
.addFile('mkdirFile.js', { content: executeMkdir }) .addFile('mkdirFile.js', { content: executeMkdir })
.executeScript('remix.exeCurrent()') .executeScript('remix.exeCurrent()')
.pause(2000) .pause(2000)
.waitForElementPresent('[data-id="treeViewLitreeViewItemTest_Folder"]', 60000) .waitForElementPresent('[data-id="treeViewLitreeViewItemTest_Folder"]', 80000)
}, },
'Should execute `readdir` api from file manager external api #group3': function (browser: NightwatchBrowser) { 'Should execute `readdir` api from file manager external api #group3': function (browser: NightwatchBrowser) {

@ -230,7 +230,13 @@ module.exports = {
}, },
'Should get current files #group7': async function (browser: NightwatchBrowser) { 'Should get current files #group7': async function (browser: NightwatchBrowser) {
await clickAndCheckLog(browser, 'fileManager:readdir', { contracts: { isDirectory: true }, scripts: { isDirectory: true }, tests: { isDirectory: true }, 'README.txt': { isDirectory: false } }, null, '/') await clickAndCheckLog(browser, 'fileManager:readdir', {
'compiler_config.json': { isDirectory: false },
contracts: { isDirectory: true },
scripts: { isDirectory: true },
tests: { isDirectory: true },
'README.txt': { isDirectory: false }
}, null, '/')
}, },
'Should throw error on current file #group7': async function (browser: NightwatchBrowser) { 'Should throw error on current file #group7': async function (browser: NightwatchBrowser) {
await clickAndCheckLog(browser, 'fileManager:getCurrentFile', 'Error from IDE : Error: No such file or directory No file selected', null, null) await clickAndCheckLog(browser, 'fileManager:getCurrentFile', 'Error from IDE : Error: No such file or directory No file selected', null, null)
@ -280,12 +286,20 @@ module.exports = {
'Should create empty workspace #group2': async function (browser: NightwatchBrowser) { 'Should create empty workspace #group2': async function (browser: NightwatchBrowser) {
await clickAndCheckLog(browser, 'filePanel:createWorkspace', null, null, ['emptyworkspace', true]) await clickAndCheckLog(browser, 'filePanel:createWorkspace', null, null, ['emptyworkspace', true])
await clickAndCheckLog(browser, 'filePanel:getCurrentWorkspace', { name: 'emptyworkspace', isLocalhost: false, absolutePath: '.workspaces/emptyworkspace' }, null, null) await clickAndCheckLog(browser, 'filePanel:getCurrentWorkspace', { name: 'emptyworkspace', isLocalhost: false, absolutePath: '.workspaces/emptyworkspace' }, null, null)
await clickAndCheckLog(browser, 'fileManager:readdir', {}, null, '/') await clickAndCheckLog(browser, 'fileManager:readdir', {
'compiler_config.json': { isDirectory: false }
}, null, '/')
}, },
'Should create workspace #group2': async function (browser: NightwatchBrowser) { 'Should create workspace #group2': async function (browser: NightwatchBrowser) {
await clickAndCheckLog(browser, 'filePanel:createWorkspace', null, null, 'testspace') await clickAndCheckLog(browser, 'filePanel:createWorkspace', null, null, 'testspace')
await clickAndCheckLog(browser, 'filePanel:getCurrentWorkspace', { name: 'testspace', isLocalhost: false, absolutePath: '.workspaces/testspace' }, null, null) await clickAndCheckLog(browser, 'filePanel:getCurrentWorkspace', { name: 'testspace', isLocalhost: false, absolutePath: '.workspaces/testspace' }, null, null)
await clickAndCheckLog(browser, 'fileManager:readdir', { contracts: { isDirectory: true }, scripts: { isDirectory: true }, tests: { isDirectory: true }, 'README.txt': { isDirectory: false } }, null, null) await clickAndCheckLog(browser, 'fileManager:readdir', {
'compiler_config.json': { isDirectory: false },
contracts: { isDirectory: true },
scripts: { isDirectory: true },
tests: { isDirectory: true },
'README.txt': { isDirectory: false }
}, null, null)
}, },
'Should get all workspaces #group2': async function (browser: NightwatchBrowser) { 'Should get all workspaces #group2': async function (browser: NightwatchBrowser) {
await clickAndCheckLog(browser, 'filePanel:getWorkspaces', ['default_workspace', 'emptyworkspace', 'testspace'], null, null) await clickAndCheckLog(browser, 'filePanel:getWorkspaces', ['default_workspace', 'emptyworkspace', 'testspace'], null, null)
@ -409,7 +423,7 @@ module.exports = {
.addFile('test_modal.js', { content: testModalToasterApi }) .addFile('test_modal.js', { content: testModalToasterApi })
.executeScript('remix.execute(\'test_modal.js\')') .executeScript('remix.execute(\'test_modal.js\')')
.useCss() .useCss()
.waitForElementVisible('*[data-id="test_id_1_ModalDialogModalBody-react"]') .waitForElementVisible('*[data-id="test_id_1_ModalDialogModalBody-react"]', 60000)
.assert.containsText('*[data-id="test_id_1_ModalDialogModalBody-react"]', 'message 1') .assert.containsText('*[data-id="test_id_1_ModalDialogModalBody-react"]', 'message 1')
.modalFooterOKClick('test_id_1_') .modalFooterOKClick('test_id_1_')
// check the script runner notifications // check the script runner notifications

@ -17,7 +17,7 @@ module.exports = {
.pause(5000) .pause(5000)
.clickLaunchIcon('udapp') .clickLaunchIcon('udapp')
.selectAccount('0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c') // this account will be used for this test suite .selectAccount('0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c') // this account will be used for this test suite
.click('[data-id="udapp_arrow"]') .click('[data-id="udappRecorderTitleExpander"]')
.click('[data-id="runtransaction"]') .click('[data-id="runtransaction"]')
.clickInstance(0) .clickInstance(0)
.clickInstance(1) .clickInstance(1)

@ -81,6 +81,7 @@ module.exports = {
.refresh() .refresh()
.pause(5000) .pause(5000)
.clickLaunchIcon('solidity') .clickLaunchIcon('solidity')
.click('*[data-id="scConfigExpander"]')
.assert.containsText('#versionSelector option[data-id="selected"]', '0.7.4+commit.3f05b770') .assert.containsText('#versionSelector option[data-id="selected"]', '0.7.4+commit.3f05b770')
.assert.containsText('#evmVersionSelector option[data-id="selected"]', 'istanbul') .assert.containsText('#evmVersionSelector option[data-id="selected"]', 'istanbul')
.assert.containsText('#compilierLanguageSelector option[data-id="selected"]', 'Yul') .assert.containsText('#compilierLanguageSelector option[data-id="selected"]', 'Yul')
@ -96,6 +97,7 @@ module.exports = {
.pause(5000) .pause(5000)
.clickLaunchIcon('solidity') .clickLaunchIcon('solidity')
.pause(5000) .pause(5000)
.click('*[data-id="scConfigExpander"]')
.assert.containsText('#versionSelector option[data-id="selected"]', 'custom') .assert.containsText('#versionSelector option[data-id="selected"]', 'custom')
// default values // default values
.assert.containsText('#evmVersionSelector option[data-id="selected"]', 'default') .assert.containsText('#evmVersionSelector option[data-id="selected"]', 'default')

@ -50,11 +50,42 @@ module.exports = {
.assert.elementPresent('*[data-id="treeViewLitreeViewItemcontracts/3_Ballot.sol"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemcontracts/3_Ballot.sol"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]')
// check js and ts files are not transformed
.click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]')
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`import { deploy } from './web3-lib'`) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]')
.click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]')
.pause(100)
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`import { deploy } from './ethers-lib'`) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]')
.click('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]')
.pause(2000)
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array<any>, from?: string, gas?: number): Promise<any> => {`) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]')
.click('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]')
.pause(100)
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array<any>, from?: string): Promise<any> => { `) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemtests"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemtests"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemtests/storage.test.js"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemtests/storage.test.js"]')
.click('*[data-id="treeViewLitreeViewItemtests/storage.test.js"]')
.pause(100)
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`const { expect } = require("chai");`) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemtests/Ballot_test.sol"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemtests/Ballot_test.sol"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemREADME.txt"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemREADME.txt"]')
}, },
@ -70,14 +101,14 @@ module.exports = {
.click('select[id="wstemplate"] option[value=blank]') .click('select[id="wstemplate"] option[value=blank]')
.waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok')
.execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() })
.pause(1000) .pause(100)
.assert.elementPresent('*[data-id="treeViewUltreeViewMenu"]') .assert.elementPresent('*[data-id="treeViewUltreeViewMenu"]')
.execute(function () { .execute(function () {
const fileList = document.querySelector('*[data-id="treeViewUltreeViewMenu"]') const fileList = document.querySelector('*[data-id="treeViewUltreeViewMenu"]')
return fileList.getElementsByTagName('li').length; return fileList.getElementsByTagName('li').length;
}, [], function(result){ }, [], function(result){
// check there are no files in FE // check there are no files in FE except config file
browser.assert.equal(result.value, 0, 'Incorrect number of files'); browser.assert.equal(result.value, 1, 'Incorrect number of files');
}); });
}, },
@ -92,18 +123,91 @@ module.exports = {
.click('select[id="wstemplate"] option[value=ozerc20]') .click('select[id="wstemplate"] option[value=ozerc20]')
.waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok')
.execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() })
.pause(1000) .pause(100)
.assert.elementPresent('*[data-id="treeViewLitreeViewItemcontracts"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemcontracts"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemcontracts/SampleERC20.sol"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemcontracts/SampleERC20.sol"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]')
// check js and ts files are not transformed
.click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]')
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`import { deploy } from './web3-lib'`) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]')
.click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]')
.pause(100)
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`import { deploy } from './ethers-lib'`) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]')
.click('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]')
.pause(100)
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array<any>, from?: string, gas?: number): Promise<any> => {`) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]')
.click('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]')
.pause(100)
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array<any>, from?: string): Promise<any> => { `) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemtests"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemtests"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemtests/SampleERC20_test.sol"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemtests/SampleERC20_test.sol"]')
}, },
'Should create ERC721 workspace with files': function (browser: NightwatchBrowser) {
browser
.click('*[data-id="workspaceCreate"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
.waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > span')
// eslint-disable-next-line dot-notation
.execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'workspace_erc721' })
.click('select[id="wstemplate"]')
.click('select[id="wstemplate"] option[value=ozerc721]')
.waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok')
.execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() })
.pause(100)
.assert.elementPresent('*[data-id="treeViewLitreeViewItemcontracts"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemcontracts/SampleERC721.sol"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]')
// check js and ts files are not transformed
.click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]')
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`import { deploy } from './web3-lib'`) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]')
.click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]')
.pause(100)
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`import { deploy } from './ethers-lib'`) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]')
.click('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]')
.pause(100)
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array<any>, from?: string, gas?: number): Promise<any> => {`) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]')
.click('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]')
.pause(100)
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array<any>, from?: string): Promise<any> => { `) !== -1,
'Incorrect content')
})
.assert.elementPresent('*[data-id="treeViewLitreeViewItemtests"]')
.assert.elementPresent('*[data-id="treeViewLitreeViewItemtests/SampleERC721_test.sol"]')
},
// WORKSPACE TEMPLATES E2E END // WORKSPACE TEMPLATES E2E END
'Should create two workspace and switch to the first one': function (browser: NightwatchBrowser) { 'Should create two workspace and switch to the first one': function (browser: NightwatchBrowser) {

@ -9,8 +9,8 @@ branches:
- master - master
- remix_live - remix_live
script: script:
- npm install - yarn install
- npm run lint && npm run test && npm run make-mock-compiler && npm run build - yarn run lint && yarn run test && yarn run make-mock-compiler && yarn run build
- wget http://selenium-release.storage.googleapis.com/3.5/selenium-server-standalone-3.5.3.jar - wget http://selenium-release.storage.googleapis.com/3.5/selenium-server-standalone-3.5.3.jar
- wget http://chromedriver.storage.googleapis.com/2.30/chromedriver_linux64.zip - wget http://chromedriver.storage.googleapis.com/2.30/chromedriver_linux64.zip
- unzip chromedriver_linux64.zip - unzip chromedriver_linux64.zip

@ -26,7 +26,7 @@ Install **npm** and **node.js** (see https://docs.npmjs.com/getting-started/inst
Remix-ide has been published as an npm module: Remix-ide has been published as an npm module:
```bash ```bash
npm install remix-ide -g yarn global add remix-ide
remix-ide remix-ide
``` ```
Or if you want to clone the github repository (`wget` need to be installed first) : Or if you want to clone the github repository (`wget` need to be installed first) :
@ -36,12 +36,12 @@ git clone https://github.com/ethereum/remix-ide.git
git clone https://github.com/ethereum/remix.git # only if you plan to link remix and remix-ide repositories and develop on it. git clone https://github.com/ethereum/remix.git # only if you plan to link remix and remix-ide repositories and develop on it.
cd remix # only if you plan to link remix and remix-ide repositories and develop on it. cd remix # only if you plan to link remix and remix-ide repositories and develop on it.
npm install # only if you plan to link remix and remix-ide repositories and develop on it. yarn install # only if you plan to link remix and remix-ide repositories and develop on it.
npm run bootstrap # only if you plan to link remix and remix-ide repositories and develop on it. yarn run bootstrap # only if you plan to link remix and remix-ide repositories and develop on it.
cd remix-ide cd remix-ide
npm install yarn install
npm run setupremix # only if you plan to link remix and remix-ide repositories and develop on it. yarn run setupremix # only if you plan to link remix and remix-ide repositories and develop on it.
npm start npm start
``` ```
@ -112,40 +112,40 @@ nvm --version
Register new unit test files in `test/index.js`. Register new unit test files in `test/index.js`.
The tests are written using [tape](https://www.npmjs.com/package/tape). The tests are written using [tape](https://www.npmjs.com/package/tape).
Run the unit tests via: `npm test` Run the unit tests via: `yarn test`
For local headless browser tests run `npm run test-browser` For local headless browser tests run `yarn run test-browser`
(requires Selenium to be installed - can be done with `npm run selenium-install`) (requires Selenium to be installed - can be done with `yarn run selenium-install`)
Running unit tests via `npm test` requires at least node v7.0.0 Running unit tests via `yarn test` requires at least node v7.0.0
## Browser Testing ## Browser Testing
To run the Selenium tests via Nightwatch: To run the Selenium tests via Nightwatch:
- Build Remix IDE and serve it: `npm run build && npm run serve` # starts web server at localhost:8080 - Build Remix IDE and serve it: `yarn run build && yarn run serve` # starts web server at localhost:8080
- Make sure Selenium is installed `npm run selenium-install` # don't need to repeat - Make sure Selenium is installed `yarn run selenium-install` # don't need to repeat
- Run a selenium server `npm run selenium` - Run a selenium server `yarn run selenium`
- Run all the tests `npm run nightwatch_local_firefox` or `npm run nightwatch_local_chrome` - Run all the tests `yarn run nightwatch_local_firefox` or `yarn run nightwatch_local_chrome`
- Or run a specific test case: - Or run a specific test case:
- npm run nightwatch_local_ballot - yarn run nightwatch_local_ballot
- npm run nightwatch_local_libraryDeployment - yarn run nightwatch_local_libraryDeployment
- npm run nightwatch_local_solidityImport - yarn run nightwatch_local_solidityImport
- npm run nightwatch_local_recorder - yarn run nightwatch_local_recorder
- npm run nightwatch_local_transactionExecution - yarn run nightwatch_local_transactionExecution
- npm run nightwatch_local_staticAnalysis - yarn run nightwatch_local_staticAnalysis
- npm run nightwatch_local_signingMessage - yarn run nightwatch_local_signingMessage
- npm run nightwatch_local_console - yarn run nightwatch_local_console
- npm run nightwatch_local_remixd # remixd needs to be run - yarn run nightwatch_local_remixd # remixd needs to be run
**NOTE:** **NOTE:**
- **the `ballot` tests suite** requires to run `ganache-cli` locally. - **the `ballot` tests suite** requires to run `ganache-cli` locally.

@ -6,14 +6,14 @@ BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}}
echo "$BUILD_ID" echo "$BUILD_ID"
TEST_EXITCODE=0 TEST_EXITCODE=0
npm run ganache-cli & yarn run ganache-cli &
npm run serve:production & yarn run serve:production &
echo 'sharing folder: ' $PWD '/apps/remix-ide/contracts' & echo 'sharing folder: ' $PWD '/apps/remix-ide/contracts' &
npm run remixd & yarn run remixd &
sleep 5 sleep 5
npm run build:e2e yarn run build:e2e
TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "\.spec\|\.test" | sort | circleci tests split ) TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "\.spec\|\.test" | sort | circleci tests split )
for TESTFILE in $TESTFILES; do for TESTFILE in $TESTFILES; do

@ -15,13 +15,13 @@ BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}}
echo "$BUILD_ID" echo "$BUILD_ID"
TEST_EXITCODE=0 TEST_EXITCODE=0
npm run ganache-cli & yarn run ganache-cli &
npm run serve & yarn run serve &
setupRemixd setupRemixd
sleep 5 sleep 5
npm run nightwatch_parallel || TEST_EXITCODE=1 yarn run nightwatch_parallel || TEST_EXITCODE=1
TESTFILES=$(circleci tests glob "./apps/remix-ide/test-browser/tests/**/*.test.js" | circleci tests split ) TESTFILES=$(circleci tests glob "./apps/remix-ide/test-browser/tests/**/*.test.js" | circleci tests split )
for TESTFILE in $TESTFILES; do for TESTFILE in $TESTFILES; do
./node_modules/.bin/nightwatch --config ./apps/remix-ide/nightwatch.js --env chrome $TESTFILE || TEST_EXITCODE=1 ./node_modules/.bin/nightwatch --config ./apps/remix-ide/nightwatch.js --env chrome $TESTFILE || TEST_EXITCODE=1

@ -6,13 +6,13 @@ BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}}
echo "$BUILD_ID" echo "$BUILD_ID"
TEST_EXITCODE=0 TEST_EXITCODE=0
npm run ganache-cli & yarn run ganache-cli &
npm run serve:production & yarn run serve:production &
npx nx serve remix-ide-e2e-src-local-plugin & npx nx serve remix-ide-e2e-src-local-plugin &
sleep 5 sleep 5
npm run build:e2e yarn run build:e2e
TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "plugin_api" | sort | circleci tests split ) TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "plugin_api" | sort | circleci tests split )
for TESTFILE in $TESTFILES; do for TESTFILE in $TESTFILES; do

@ -2,7 +2,7 @@
set -e set -e
npm run build:e2e yarn run build:e2e
TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "\.flaky" | sort ) TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "\.flaky" | sort )
# count test files # count test files
@ -18,10 +18,10 @@ BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}}
echo "$BUILD_ID" echo "$BUILD_ID"
TEST_EXITCODE=0 TEST_EXITCODE=0
npm run ganache-cli & yarn run ganache-cli &
npm run serve:production & yarn run serve:production &
echo 'sharing folder: ' $PWD '/apps/remix-ide/contracts' & echo 'sharing folder: ' $PWD '/apps/remix-ide/contracts' &
npm run remixd & yarn run remixd &
npx nx serve remix-ide-e2e-src-local-plugin & npx nx serve remix-ide-e2e-src-local-plugin &
sleep 5 sleep 5

@ -13,7 +13,7 @@ KEYS=$(jq -r '.projects | keys' workspace.json | tr -d '[],"')
then then
echo ${row} echo ${row}
fi fi
done) | circleci tests split | { while read i;do npm run lint $i; done } done) | circleci tests split | { while read i;do yarn run lint $i; done }
echo "$TEST_EXITCODE" echo "$TEST_EXITCODE"
if [ "$TEST_EXITCODE" -eq 1 ] if [ "$TEST_EXITCODE" -eq 1 ]

@ -5,6 +5,6 @@ So if you've found the documentation to Remix but don't know where to find Remix
- An online version is available at [https://remix.ethereum.org](https://remix.ethereum.org). This version is stable and is updated at almost every release. - An online version is available at [https://remix.ethereum.org](https://remix.ethereum.org). This version is stable and is updated at almost every release.
- An alpha online version is available at [https://remix-alpha.ethereum.org](https://remix-alpha.ethereum.org). This is not a stable version. - An alpha online version is available at [https://remix-alpha.ethereum.org](https://remix-alpha.ethereum.org). This is not a stable version.
- npm `remix-ide` package `npm install remix-ide -g`. `remix-ide` create a new instance of `Remix IDE` available at [http://127.0.0.1:8080](http://127.0.0.1:8080) and make the current folder available to Remix IDE by automatically starting `remixd`. - npm `remix-ide` package `yarn global add remix-ide`. `remix-ide` create a new instance of `Remix IDE` available at [http://127.0.0.1:8080](http://127.0.0.1:8080) and make the current folder available to Remix IDE by automatically starting `remixd`.
see [Connection to `remixd`](https://remix-ide.readthedocs.io/en/latest/remixd.html) for more information about sharing local file with `Remix IDE`. see [Connection to `remixd`](https://remix-ide.readthedocs.io/en/latest/remixd.html) for more information about sharing local file with `Remix IDE`.
- Github release: [https://github.com/ethereum/remix-ide/releases](https://github.com/ethereum/remix-ide/releases) . The source code is packaged at every release but still need to be built using `npm run build`. - Github release: [https://github.com/ethereum/remix-ide/releases](https://github.com/ethereum/remix-ide/releases) . The source code is packaged at every release but still need to be built using `yarn run build`.

@ -8,10 +8,7 @@ The code of `remixd` is
[here](https://github.com/ethereum/remixd) . [here](https://github.com/ethereum/remixd) .
`remixd` can be globally installed using the following command: `remixd` can be globally installed using the following command:
`npm install -g remixd` `yarn global add @remix-project/remixd`
Or just install it in the directory of your choice by removing the -g flag:
`npm install remixd`
Then from the terminal, the command `remixd -s <absolute-path-to-the-shared-folder> --remix-ide <your-remix-ide-URL-instance>` will start `remixd` and will share the given folder with remix-ide. Then from the terminal, the command `remixd -s <absolute-path-to-the-shared-folder> --remix-ide <your-remix-ide-URL-instance>` will start `remixd` and will share the given folder with remix-ide.

@ -9,7 +9,6 @@ This document includes:
- git checkout origin/master - git checkout origin/master
- git checkout -b bumpVersion - git checkout -b bumpVersion
- update package.json version - update package.json version
- remove package-lock.json version and generate a new one with `npm install`
- merge PR - merge PR
- git fetch origin master - git fetch origin master
- git checkout origin/master - git checkout origin/master
@ -18,9 +17,9 @@ This document includes:
- github-changes -o ethereum -r remix-ide -a --only-pulls --use-commit-body --only-merges --between-tags previous_version...next_version - github-changes -o ethereum -r remix-ide -a --only-pulls --use-commit-body --only-merges --between-tags previous_version...next_version
- publish a release in github using the changelog - publish a release in github using the changelog
- rm -rf node_modules - rm -rf node_modules
- npm install - yarn install
- remove all soljson.js files in root folder - remove all soljson.js files in root folder
- npm run build - yarn run build
- npm publish - npm publish
- after remix_live is updated, drop the zip (from https://github.com/ethereum/remix-live/) to the release. - after remix_live is updated, drop the zip (from https://github.com/ethereum/remix-live/) to the release.
@ -29,7 +28,6 @@ This document includes:
- git checkout origin/master - git checkout origin/master
- git checkout -b bumpVersion - git checkout -b bumpVersion
- update package.json version to the new version "vx.x.x-beta.1" - update package.json version to the new version "vx.x.x-beta.1"
- remove package-lock/json version and generate a new one with `npm install`
- merge PR - merge PR
- git fetch origin master - git fetch origin master
- git checkout origin/master - git checkout origin/master

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 418 KiB

@ -24,7 +24,7 @@ export class TabProxy extends Plugin {
this.themeQuality = 'dark' this.themeQuality = 'dark'
} }
onActivation () { async onActivation () {
this.on('theme', 'themeChanged', (theme) => { this.on('theme', 'themeChanged', (theme) => {
this.themeQuality = theme.quality this.themeQuality = theme.quality
// update invert for all icons // update invert for all icons
@ -169,6 +169,13 @@ export class TabProxy extends Plugin {
this.on('manager', 'pluginDeactivated', (profile) => { this.on('manager', 'pluginDeactivated', (profile) => {
this.removeTab(profile.name) this.removeTab(profile.name)
}) })
try {
this.themeQuality = (await this.call('theme', 'currentTheme') ).quality
} catch (e) {
console.log('theme plugin has an issue: ', e)
}
this.renderComponent()
} }
focus (name) { focus (name) {
@ -208,6 +215,7 @@ export class TabProxy extends Plugin {
} }
renameTab (oldName, newName) { renameTab (oldName, newName) {
// The new tab is being added by FileManager
this.removeTab(oldName) this.removeTab(oldName)
} }
@ -292,7 +300,15 @@ export class TabProxy extends Plugin {
} }
updateComponent(state) { updateComponent(state) {
return <TabsUI tabs={state.loadedTabs} onSelect={state.onSelect} onClose={state.onClose} onZoomIn={state.onZoomIn} onZoomOut={state.onZoomOut} onReady={state.onReady} themeQuality={state.themeQuality} /> return <TabsUI
tabs={state.loadedTabs}
onSelect={state.onSelect}
onClose={state.onClose}
onZoomIn={state.onZoomIn}
onZoomOut={state.onZoomOut}
onReady={state.onReady}
themeQuality={state.themeQuality}
/>
} }
renderComponent () { renderComponent () {

@ -18,7 +18,7 @@ export class ConfigPlugin extends Plugin {
const queryParams = new QueryParams() const queryParams = new QueryParams()
const params = queryParams.get() const params = queryParams.get()
const config = Registry.getInstance().get('config').api const config = Registry.getInstance().get('config').api
let param = params[name] || config.get(name) || config.get('settings/' + name) const param = params[name] || config.get(name) || config.get('settings/' + name)
if (param === 'true') return true if (param === 'true') return true
if (param === 'false') return false if (param === 'false') return false
return param return param

@ -23,7 +23,7 @@ export class GanacheProvider extends AbstractProvider {
body (): JSX.Element { body (): JSX.Element {
return ( return (
<div> Note: To run Ganache on your system, run <div> Note: To run Ganache on your system, run
<div className="border p-1">npm install -g ganache</div> <div className="border p-1">yarn global add ganache</div>
<div className="border p-1">ganache</div> <div className="border p-1">ganache</div>
For more info, visit: <a href="https://github.com/trufflesuite/ganache" target="_blank">Ganache Documentation</a> For more info, visit: <a href="https://github.com/trufflesuite/ganache" target="_blank">Ganache Documentation</a>
<div>Ganache JSON-RPC Endpoint:</div> <div>Ganache JSON-RPC Endpoint:</div>

@ -7,7 +7,7 @@ const _paq = window._paq = window._paq || []
const requiredModules = [ // services + layout views + system views const requiredModules = [ // services + layout views + system views
'manager', 'config', 'compilerArtefacts', 'compilerMetadata', 'contextualListener', 'editor', 'offsetToLineColumnConverter', 'network', 'theme', 'manager', 'config', 'compilerArtefacts', 'compilerMetadata', 'contextualListener', 'editor', 'offsetToLineColumnConverter', 'network', 'theme',
'fileManager', 'contentImport', 'blockchain', 'web3Provider', 'scriptRunner', 'fetchAndCompile', 'mainPanel', 'hiddenPanel', 'sidePanel', 'menuicons', 'fileManager', 'contentImport', 'blockchain', 'web3Provider', 'scriptRunner', 'fetchAndCompile', 'mainPanel', 'hiddenPanel', 'sidePanel', 'menuicons',
'filePanel', 'terminal', 'settings', 'pluginManager', 'tabs', 'udapp', 'dGitProvider', 'solidity-logic', 'gistHandler', 'layout', 'filePanel', 'terminal', 'settings', 'pluginManager', 'tabs', 'udapp', 'dGitProvider', 'solidity', 'solidity-logic', 'gistHandler', 'layout',
'notification', 'permissionhandler', 'walkthrough', 'storage', 'restorebackupzip', 'link-libraries', 'deploy-libraries', 'openzeppelin-proxy', 'hardhat-provider', 'compileAndRun', 'search'] 'notification', 'permissionhandler', 'walkthrough', 'storage', 'restorebackupzip', 'link-libraries', 'deploy-libraries', 'openzeppelin-proxy', 'hardhat-provider', 'compileAndRun', 'search']
const dependentModules = ['git', 'hardhat', 'truffle', 'slither'] // module which shouldn't be manually activated (e.g git is activated by remixd) const dependentModules = ['git', 'hardhat', 'truffle', 'slither'] // module which shouldn't be manually activated (e.g git is activated by remixd)
@ -19,7 +19,8 @@ const sensitiveCalls = {
} }
export function isNative(name) { export function isNative(name) {
const nativePlugins = ['vyper', 'workshops', 'debugger', 'remixd', 'menuicons', 'solidity', 'hardhat-provider', 'solidityStaticAnalysis', 'solidityUnitTesting', 'layout', 'notification', 'hardhat-provider', 'ganache-provider'] const nativePlugins = ['vyper', 'workshops', 'debugger', 'remixd', 'menuicons', 'solidity', 'solidity-logic',
'hardhat-provider', 'solidityStaticAnalysis', 'solidityUnitTesting', 'layout', 'notification', 'hardhat-provider', 'ganache-provider']
return nativePlugins.includes(name) || requiredModules.includes(name) return nativePlugins.includes(name) || requiredModules.includes(name)
} }

@ -18,7 +18,7 @@ export const CompilerApiMixin = (Base) => class extends Base {
onCurrentFileChanged: (fileName: string) => void onCurrentFileChanged: (fileName: string) => void
// onResetResults: () => void // onResetResults: () => void
onSetWorkspace: (workspace: any) => void onSetWorkspace: (isLocalhost: boolean, workspaceName: string) => void
onNoFileSelected: () => void onNoFileSelected: () => void
onCompilationFinished: (compilationDetails: { contractMap: { file: string } | Record<string, any>, contractsDetails: Record<string, any> }) => void onCompilationFinished: (compilationDetails: { contractMap: { file: string } | Record<string, any>, contractsDetails: Record<string, any> }) => void
onSessionSwitched: () => void onSessionSwitched: () => void
@ -237,12 +237,12 @@ export const CompilerApiMixin = (Base) => class extends Base {
this.on('filePanel', 'setWorkspace', (workspace) => { this.on('filePanel', 'setWorkspace', (workspace) => {
this.resetResults() this.resetResults()
if (this.onSetWorkspace) this.onSetWorkspace(workspace.isLocalhost) if (this.onSetWorkspace) this.onSetWorkspace(workspace.isLocalhost, workspace.name)
}) })
this.on('remixd', 'rootFolderChanged', () => { this.on('remixd', 'rootFolderChanged', () => {
this.resetResults() this.resetResults()
if (this.onSetWorkspace) this.onSetWorkspace(true) if (this.onSetWorkspace) this.onSetWorkspace(true, 'localhost')
}) })
this.on('editor', 'sessionSwitched', () => { this.on('editor', 'sessionSwitched', () => {

@ -6,31 +6,14 @@ import { CompilerApiMixin } from './compiler-api'
import { ICompilerApi } from '@remix-project/remix-lib-ts' import { ICompilerApi } from '@remix-project/remix-lib-ts'
import { CompileTabLogic } from '@remix-ui/solidity-compiler' import { CompileTabLogic } from '@remix-ui/solidity-compiler'
const profile = {
name: 'solidity',
displayName: 'Solidity compiler',
icon: 'assets/img/solidity.webp',
description: 'Compile solidity contracts',
kind: 'compiler',
permission: true,
location: 'sidePanel',
documentation: 'https://remix-ide.readthedocs.io/en/latest/solidity_editor.html',
version: '0.0.1',
methods: ['getCompilationResult', 'compile', 'compileWithParameters', 'setCompilerConfig', 'compileFile', 'getCompilerState']
}
const defaultAppParameters = {
hideWarnings: false,
autoCompile: false,
includeNightlies: false
}
const defaultCompilerParameters = { const defaultCompilerParameters = {
runs: '200', runs: '200',
optimize: false, optimize: false,
version: 'soljson-v0.8.7+commit.e28d00a7', version: 'soljson-v0.8.7+commit.e28d00a7',
evmVersion: null, // compiler default evmVersion: null, // compiler default
language: 'Solidity' language: 'Solidity',
useFileConfiguration: false,
configFilePath: "compiler_config.json"
} }
export class CompilerClientApi extends CompilerApiMixin(PluginClient) implements ICompilerApi { export class CompilerClientApi extends CompilerApiMixin(PluginClient) implements ICompilerApi {
constructor () { constructor () {
@ -48,7 +31,9 @@ export class CompilerClientApi extends CompilerApiMixin(PluginClient) implements
optimize: localStorage.getItem('optimize') === 'true', optimize: localStorage.getItem('optimize') === 'true',
version: localStorage.getItem('version') || defaultCompilerParameters.version, version: localStorage.getItem('version') || defaultCompilerParameters.version,
evmVersion: localStorage.getItem('evmVersion') || defaultCompilerParameters.evmVersion, // default evmVersion: localStorage.getItem('evmVersion') || defaultCompilerParameters.evmVersion, // default
language: localStorage.getItem('language') || defaultCompilerParameters.language language: localStorage.getItem('language') || defaultCompilerParameters.language,
useFileConfiguration: localStorage.getItem('useFileConfiguration') === 'true',
configFilePath: localStorage.getItem('configFilePath') || defaultCompilerParameters.configFilePath
} }
return params return params
} }

@ -10,7 +10,7 @@
### Installation ### Installation
`@remix-project/remix-analyzer` is an NPM package and can be installed using NPM as: `@remix-project/remix-analyzer` is an NPM package and can be installed using NPM as:
`npm install @remix-project/remix-analyzer` `yarn add @remix-project/remix-analyzer`
### How to use ### How to use

@ -10,7 +10,7 @@
### Installation ### Installation
`@remix-project/remix-astwalker` is an NPM package and can be installed using NPM as: `@remix-project/remix-astwalker` is an NPM package and can be installed using NPM as:
`npm install @remix-project/remix-astwalker` `yarn add @remix-project/remix-astwalker`
### How to use ### How to use

@ -10,7 +10,7 @@
### Installation ### Installation
`@remix-project/remix-debug` is an NPM package and can be installed using NPM as: `@remix-project/remix-debug` is an NPM package and can be installed using NPM as:
`npm install @remix-project/remix-debug` `yarn add @remix-project/remix-debug`
### How to use ### How to use

@ -10,7 +10,7 @@
### Installation ### Installation
`@remix-project/remix-lib` is an NPM package and can be installed using NPM as: `@remix-project/remix-lib` is an NPM package and can be installed using NPM as:
`npm install @remix-project/remix-lib` `yarn add @remix-project/remix-lib`
### How to use ### How to use

@ -24,7 +24,7 @@ export interface ICompilerApi {
onCurrentFileChanged: (fileName: string) => void onCurrentFileChanged: (fileName: string) => void
// onResetResults: () => void, // onResetResults: () => void,
onSetWorkspace: (workspace: any) => void onSetWorkspace: (isLocalhost: boolean, workspaceName: string) => void
onNoFileSelected: () => void onNoFileSelected: () => void
onCompilationFinished: (contractsDetails: any, contractMap: any) => void onCompilationFinished: (contractsDetails: any, contractMap: any) => void
onSessionSwitched: () => void onSessionSwitched: () => void

@ -10,7 +10,7 @@
### Installation ### Installation
`@remix-project/remix-simulator` is an NPM package and can be installed using NPM as: `@remix-project/remix-simulator` is an NPM package and can be installed using NPM as:
`npm install @remix-project/remix-simulator` `yarn add @remix-project/remix-simulator`
### How to use ### How to use

@ -12,7 +12,7 @@
`@remix-project/remix-solidity` is an NPM package and can be installed using NPM as: `@remix-project/remix-solidity` is an NPM package and can be installed using NPM as:
`npm install @remix-project/remix-solidity` `yarn add @remix-project/remix-solidity`
### How to use ### How to use

@ -50,3 +50,9 @@ export function getValidLanguage (val: string): Language {
} }
return null return null
} }
export function compilerInputForConfigFile(sources: Source, opts)
{
opts.sources = sources
return JSON.stringify(opts)
}

@ -2,7 +2,7 @@
import { update } from 'solc/abi' import { update } from 'solc/abi'
import * as webworkify from 'webworkify-webpack' import * as webworkify from 'webworkify-webpack'
import compilerInput from './compiler-input' import compilerInput, { compilerInputForConfigFile } from './compiler-input'
import EventManager from '../lib/eventManager' import EventManager from '../lib/eventManager'
import txHelper from './helper' import txHelper from './helper'
import { import {
@ -31,6 +31,8 @@ export class Compiler {
language: 'Solidity', language: 'Solidity',
compilationStartTime: null, compilationStartTime: null,
target: null, target: null,
useFileConfiguration: false,
configFileContent: '',
lastCompilationResult: { lastCompilationResult: {
data: null, data: null,
source: null source: null
@ -111,11 +113,17 @@ export class Compiler {
return { error: 'Deferred import' } return { error: 'Deferred import' }
} }
let result: CompilationResult = {} let result: CompilationResult = {}
let input let input = ""
try { try {
if (source && source.sources) { if (source && source.sources) {
const { optimize, runs, evmVersion, language } = this.state const { optimize, runs, evmVersion, language, useFileConfiguration, configFileContent } = this.state
if (useFileConfiguration) {
input = compilerInputForConfigFile(source.sources, JSON.parse(configFileContent))
} else {
input = compilerInput(source.sources, { optimize, runs, evmVersion, language }) input = compilerInput(source.sources, { optimize, runs, evmVersion, language })
}
result = JSON.parse(compiler.compile(input, { import: missingInputsCallback })) result = JSON.parse(compiler.compile(input, { import: missingInputsCallback }))
} }
} catch (exception) { } catch (exception) {
@ -184,11 +192,17 @@ export class Compiler {
return { error: 'Deferred import' } return { error: 'Deferred import' }
} }
let result: CompilationResult = {} let result: CompilationResult = {}
let input: string let input = ""
try { try {
if (source && source.sources) { if (source && source.sources) {
const { optimize, runs, evmVersion, language } = this.state const { optimize, runs, evmVersion, language, useFileConfiguration, configFileContent } = this.state
if (useFileConfiguration) {
input = compilerInputForConfigFile(source.sources, JSON.parse(configFileContent))
} else {
input = compilerInput(source.sources, { optimize, runs, evmVersion, language }) input = compilerInput(source.sources, { optimize, runs, evmVersion, language })
}
result = JSON.parse(remoteCompiler.compile(input, { import: missingInputsCallback })) result = JSON.parse(remoteCompiler.compile(input, { import: missingInputsCallback }))
} }
} catch (exception) { } catch (exception) {
@ -290,12 +304,26 @@ export class Compiler {
this.state.compileJSON = (source: SourceWithTarget) => { this.state.compileJSON = (source: SourceWithTarget) => {
if (source && source.sources) { if (source && source.sources) {
const { optimize, runs, evmVersion, language } = this.state const { optimize, runs, evmVersion, language, useFileConfiguration, configFileContent } = this.state
jobs.push({ sources: source }) jobs.push({ sources: source })
let input = ""
try {
if (useFileConfiguration) {
input = compilerInputForConfigFile(source.sources, JSON.parse(configFileContent))
} else {
input = compilerInput(source.sources, { optimize, runs, evmVersion, language })
}
} catch (exception) {
this.onCompilationFinished({ error: { formattedMessage: exception.message } }, [], source, "", this.state.currentVersion)
return
}
this.state.worker.postMessage({ this.state.worker.postMessage({
cmd: 'compile', cmd: 'compile',
job: jobs.length - 1, job: jobs.length - 1,
input: compilerInput(source.sources, { optimize, runs, evmVersion, language }) input: input
}) })
} }
} }

@ -165,6 +165,8 @@ export interface CompilerState {
language: Language, language: Language,
compilationStartTime: number| null, compilationStartTime: number| null,
target: string | null, target: string | null,
useFileConfiguration: boolean,
configFileContent: string,
lastCompilationResult: { lastCompilationResult: {
data: CompilationResult | null, data: CompilationResult | null,
source: SourceWithTarget | null | undefined source: SourceWithTarget | null | undefined

@ -12,11 +12,11 @@ To know more about Remix IDE `Solidity Unit Testing Plugin`, visit [Remix IDE of
### Installation ### Installation
* As a dev dependency: * As a dev dependency:
`npm install --save-dev @remix-project/remix-tests` `yarn add --dev @remix-project/remix-tests`
* As a global NPM module to use as CLI: * As a global NPM module to use as CLI:
`npm -g install @remix-project/remix-tests` `yarn global add @remix-project/remix-tests`
To confirm installation, run: To confirm installation, run:
``` ```

@ -11,7 +11,7 @@ describe('testRunner: remix-tests CLI', () => {
const dirContent = result.stdout.toString() const dirContent = result.stdout.toString()
// Install dependencies if 'node_modules' is not already present // Install dependencies if 'node_modules' is not already present
if(!dirContent.includes('node_modules')) { if(!dirContent.includes('node_modules')) {
execSync('npm install', { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') }) execSync('yarn install', { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') })
} }
} }

@ -83,6 +83,25 @@ export interface EditorUIProps {
export const EditorUI = (props: EditorUIProps) => { export const EditorUI = (props: EditorUIProps) => {
const [, setCurrentBreakpoints] = useState({}) const [, setCurrentBreakpoints] = useState({})
const defaultEditorValue = `
\t\t\t\t\t\t\t ____ _____ __ __ ___ __ __ ___ ____ _____
\t\t\t\t\t\t\t| _ \\ | ____| | \\/ | |_ _| \\ \\/ / |_ _| | _ \\ | ____|
\t\t\t\t\t\t\t| |_) | | _| | |\\/| | | | \\ / | | | | | | | _|
\t\t\t\t\t\t\t| _ < | |___ | | | | | | / \\ | | | |_| | | |___
\t\t\t\t\t\t\t|_| \\_\\ |_____| |_| |_| |___| /_/\\_\\ |___| |____/ |_____|\n\n
\t\t\t\t\t\t\tKeyboard Shortcuts:\n
\t\t\t\t\t\t\t\tCTRL + S: Compile the current contract\n
\t\t\t\t\t\t\t\tCtrl + Shift + F : Open the File Explorer\n
\t\t\t\t\t\t\t\tCtrl + Shift + A : Open the Plugin Manager\n
\t\t\t\t\t\t\t\tCTRL + SHIFT + S: Compile the current contract & Run an associated script\n\n
\t\t\t\t\t\t\tImportant Links:\n
\t\t\t\t\t\t\t\tOfficial website about the Remix Project: https://remix-project.org/\n
\t\t\t\t\t\t\t\tOfficial documentation: https://remix-ide.readthedocs.io/en/latest/\n
\t\t\t\t\t\t\t\tGithub: https://github.com/ethereum/remix-project\n
\t\t\t\t\t\t\t\tGitter: https://gitter.im/ethereum/remix\n
\t\t\t\t\t\t\t\tMedium: https://medium.com/remix-ide\n
\t\t\t\t\t\t\t\tTwitter: https://twitter.com/ethereumremix\n
`
const editorRef = useRef(null) const editorRef = useRef(null)
const monacoRef = useRef(null) const monacoRef = useRef(null)
const currentFileRef = useRef('') const currentFileRef = useRef('')
@ -453,7 +472,8 @@ export const EditorUI = (props: EditorUIProps) => {
language={editorModelsState[props.currentFile] ? editorModelsState[props.currentFile].language : 'text'} language={editorModelsState[props.currentFile] ? editorModelsState[props.currentFile].language : 'text'}
onMount={handleEditorDidMount} onMount={handleEditorDidMount}
beforeMount={handleEditorWillMount} beforeMount={handleEditorWillMount}
options={{ glyphMargin: true }} options={{ glyphMargin: true, readOnly: true}}
defaultValue={defaultEditorValue}
/> />
<div className="contextview"> <div className="contextview">
<RemixUiEditorContextView <RemixUiEditorContextView

@ -4,7 +4,6 @@ import './remix-ui-home-tab.css'
import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line
import { Toaster } from '@remix-ui/toaster' // eslint-disable-line import { Toaster } from '@remix-ui/toaster' // eslint-disable-line
import PluginButton from './components/pluginButton' // eslint-disable-line import PluginButton from './components/pluginButton' // eslint-disable-line
import { QueryParams } from '@remix-project/remix-lib'
import { ThemeContext, themes } from './themeContext' import { ThemeContext, themes } from './themeContext'
declare global { declare global {
interface Window { interface Window {

@ -11,8 +11,8 @@ export function InstanceContainerUI (props: InstanceContainerProps) {
} }
return ( return (
<div className="udapp_instanceContainer border-0 list-group-item"> <div className="udapp_instanceContainer mt-3 border-0 list-group-item">
<div className="d-flex justify-content-between align-items-center pl-2 ml-1 mb-2" <label className="udapp_deployedContracts d-flex justify-content-between align-items-center pl-2 mb-0"
title="Autogenerated generic user interfaces for interaction with deployed contracts"> title="Autogenerated generic user interfaces for interaction with deployed contracts">
Deployed Contracts Deployed Contracts
{ instanceList.length > 0 { instanceList.length > 0
@ -20,7 +20,7 @@ export function InstanceContainerUI (props: InstanceContainerProps) {
title="Clear instances list and reset recorder" aria-hidden="true"> title="Clear instances list and reset recorder" aria-hidden="true">
</i> : null </i> : null
} }
</div> </label>
{ instanceList.length > 0 { instanceList.length > 0
? <div> { props.instances.instanceList.map((instance, index) => { ? <div> { props.instances.instanceList.map((instance, index) => {
return <UniversalDappUI return <UniversalDappUI

@ -1,27 +1,9 @@
// eslint-disable-next-line no-use-before-define // eslint-disable-next-line no-use-before-define
import React from 'react' import React, {useState} from 'react'
import { TreeView, TreeViewItem } from '@remix-ui/tree-view'
import { RecorderProps } from '../types' import { RecorderProps } from '../types'
export function RecorderUI (props: RecorderProps) { export function RecorderUI (props: RecorderProps) {
const card = (title: string, recorderCount: number) => { const [toggleExpander, setToggleExpander] = useState<boolean>(false)
return (
<div className="d-flex justify-content-between align-items-center" onClick={() => {}}>
<div className="pr-1 d-flex flex-row">
<div>{title}</div>
<div>
<div className="d-flex flex-column">
<div className="ml-2 badge badge-pill badge-primary" title="The number of recorded transactions">{recorderCount}</div>
</div>
</div>
</div>
<div>
<div><i className="udapp_arrow fas fa-angle-down" data-id="udapp_arrow"></i></div>
</div>
</div>
)
}
const triggerRecordButton = () => { const triggerRecordButton = () => {
props.storeScenario(props.scenarioPrompt) props.storeScenario(props.scenarioPrompt)
} }
@ -30,24 +12,35 @@ export function RecorderUI (props: RecorderProps) {
props.runCurrentScenario(props.gasEstimationPrompt, props.passphrasePrompt, props.mainnetPrompt, props.logBuilder) props.runCurrentScenario(props.gasEstimationPrompt, props.passphrasePrompt, props.mainnetPrompt, props.logBuilder)
} }
const toggleClass = () => {
setToggleExpander(!toggleExpander)
}
return ( return (
<div className="udapp_cardContainer list-group-item border-0"> <div className="udapp_cardContainer list-group-item border border-bottom">
<TreeView> <div className="udapp_recorderSection d-flex justify-content-between" onClick={toggleClass}>
<TreeViewItem label={card('Transactions recorded', props.count)} showIcon={false} labelClass="ml-n1"> <div className="d-flex">
<div className="d-flex flex-column"> <label className="mt-1 udapp_recorderSectionLabel">Transactions recorded</label>
<div className="udapp_recorderDescription mt-2"> <div className="ml-2 mb-2 badge badge-pill badge-primary" title="The number of recorded transactions">{props.count}</div>
All transactions (deployed contracts and function executions) in this environment can be saved and replayed in </div>
<div>
<span data-id='udappRecorderTitleExpander' onClick={toggleClass}>
<i className={!toggleExpander ? 'fas fa-angle-right' : 'fas fa-angle-down'} aria-hidden="true"></i>
</span>
</div>
</div>
<div className={`border-bottom flex-column ${toggleExpander ? "d-flex" : "d-none"}`}>
<div className="p-2 mt-2">
All transactions (deployed contracts and function executions) can be saved and replayed in
another environment. e.g Transactions created in Javascript VM can be replayed in the Injected Web3. another environment. e.g Transactions created in Javascript VM can be replayed in the Injected Web3.
</div> </div>
<div className="udapp_transactionActions"> <div className="mb-2 udapp_transactionActions">
<i className="fas fa-save savetransaction udapp_recorder udapp_icon" <i className="fas fa-save savetransaction udapp_recorder udapp_icon"
onClick={triggerRecordButton} title="Save Transactions" aria-hidden="true"> onClick={triggerRecordButton} title="Save Transactions" aria-hidden="true">
</i> </i>
<i className="fas fa-play runtransaction udapp_runTxs udapp_icon" title="Run Transactions" data-id="runtransaction" aria-hidden="true" onClick={handleClickRunButton}></i> <i className="fas fa-play runtransaction udapp_runTxs udapp_icon" title="Run Transactions" data-id="runtransaction" aria-hidden="true" onClick={handleClickRunButton}></i>
</div> </div>
</div> </div>
</TreeViewItem>
</TreeView>
</div> </div>
) )
} }

@ -3,10 +3,3 @@
margin : 0; margin : 0;
background : none; background : none;
} }
.udapp_arrow {
font-weight : bold;
cursor : pointer;
font-size : 14px;
}
.udapp_arrow:hover {
}

@ -60,6 +60,9 @@
text-align: center; text-align: center;
padding: 0 14px 16px; padding: 0 14px 16px;
} }
.udapp_deployedContracts {
font-size: 1rem;
}
.udapp_pendingTxsContainer { .udapp_pendingTxsContainer {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -70,9 +73,6 @@
.udapp_container { .udapp_container {
padding: 0 24px 16px; padding: 0 24px 16px;
} }
.udapp_recorderDescription {
margin: 0 15px 15px 0;
}
.udapp_contractNames { .udapp_contractNames {
width: 100%; width: 100%;
border: 1px solid border: 1px solid
@ -121,7 +121,14 @@
.udapp_ataddressinput { .udapp_ataddressinput {
padding: .25rem; padding: .25rem;
} }
.udapp_create { .udapp_recorderSection:hover {
cursor: pointer;
}.udapp_recorderSectionLabel:hover {
cursor: pointer;
}
.udapp_recorderSectionLabel {
cursor: pointer;
font-size: 1rem;
} }
.udapp_input { .udapp_input {
font-size: 10px !important; font-size: 10px !important;

@ -227,7 +227,8 @@ export interface ContractGUIProps {
clickCallBack: (inputs: { name: string, type: string }[], input: string) => void, clickCallBack: (inputs: { name: string, type: string }[], input: string) => void,
widthClass?: string, widthClass?: string,
evmBC: any, evmBC: any,
lookupOnly: boolean lookupOnly: boolean,
disabled?: boolean
} }
export interface MainnetProps { export interface MainnetProps {
network: Network, network: Network,

@ -9,6 +9,7 @@ import { resetEditorMode, listenToEvents } from './actions/compiler'
import { OverlayTrigger, Tooltip } from 'react-bootstrap' // eslint-disable-line import { OverlayTrigger, Tooltip } from 'react-bootstrap' // eslint-disable-line
import { getValidLanguage } from '@remix-project/remix-solidity' import { getValidLanguage } from '@remix-project/remix-solidity'
import { CopyToClipboard } from '@remix-ui/clipboard' import { CopyToClipboard } from '@remix-ui/clipboard'
import { configFileContent } from './compilerConfiguration'
import './css/style.css' import './css/style.css'
@ -21,10 +22,12 @@ declare global {
const _paq = window._paq = window._paq || [] //eslint-disable-line const _paq = window._paq = window._paq || [] //eslint-disable-line
export const CompilerContainer = (props: CompilerContainerProps) => { export const CompilerContainer = (props: CompilerContainerProps) => {
const { api, compileTabLogic, tooltip, modal, compiledFileName, updateCurrentVersion, configurationSettings, isHardhatProject, isTruffleProject } = props // eslint-disable-line const { api, compileTabLogic, tooltip, modal, compiledFileName, updateCurrentVersion, configurationSettings, isHardhatProject, isTruffleProject, workspaceName } = props // eslint-disable-line
const [state, setState] = useState({ const [state, setState] = useState({
hideWarnings: false, hideWarnings: false,
autoCompile: false, autoCompile: false,
configFilePath: "compiler_config.json",
useFileConfiguration: false,
matomoAutocompileOnce: true, matomoAutocompileOnce: true,
optimize: false, optimize: false,
compileTimeout: null, compileTimeout: null,
@ -39,13 +42,43 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
language: 'Solidity', language: 'Solidity',
evmVersion: '' evmVersion: ''
}) })
const [showFilePathInput, setShowFilePathInput] = useState<boolean>(false)
const [toggleExpander, setToggleExpander] = useState<boolean>(false)
const [disableCompileButton, setDisableCompileButton] = useState<boolean>(false) const [disableCompileButton, setDisableCompileButton] = useState<boolean>(false)
const compileIcon = useRef(null) const compileIcon = useRef(null)
const promptMessageInput = useRef(null) const promptMessageInput = useRef(null)
const configFilePathInput = useRef(null)
const [hhCompilation, sethhCompilation] = useState(false) const [hhCompilation, sethhCompilation] = useState(false)
const [truffleCompilation, setTruffleCompilation] = useState(false) const [truffleCompilation, setTruffleCompilation] = useState(false)
const [compilerContainer, dispatch] = useReducer(compilerReducer, compilerInitialState) const [compilerContainer, dispatch] = useReducer(compilerReducer, compilerInitialState)
useEffect(() => {
api.setAppParameter('configFilePath', "/compiler_config.json")
api.fileExists("/compiler_config.json").then((exists) => {
if (!exists) createNewConfigFile()
else {
// what to do? discuss
}
})
api.setAppParameter('configFilePath', "/compiler_config.json")
setShowFilePathInput(false)
}, [workspaceName])
useEffect(() => {
const listener = (event) => {
if (configFilePathInput.current !== event.target) {
setShowFilePathInput(false)
return;
}
};
document.addEventListener("mousedown", listener);
document.addEventListener("touchstart", listener);
return () => {
document.removeEventListener("mousedown", listener);
document.removeEventListener("touchstart", listener);
}
})
useEffect(() => { useEffect(() => {
fetchAllVersion((allversions, selectedVersion, isURL) => { fetchAllVersion((allversions, selectedVersion, isURL) => {
setState(prevState => { setState(prevState => {
@ -72,6 +105,10 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
const autocompile = await api.getAppParameter('autoCompile') as boolean || false const autocompile = await api.getAppParameter('autoCompile') as boolean || false
const hideWarnings = await api.getAppParameter('hideWarnings') as boolean || false const hideWarnings = await api.getAppParameter('hideWarnings') as boolean || false
const includeNightlies = await api.getAppParameter('includeNightlies') as boolean || false const includeNightlies = await api.getAppParameter('includeNightlies') as boolean || false
const useFileConfiguration = await api.getAppParameter('useFileConfiguration') as boolean || false
let configFilePath = await api.getAppParameter('configFilePath')
if (!configFilePath || configFilePath == '') configFilePath = "/compiler_config.json"
setState(prevState => { setState(prevState => {
const params = api.getCompilerParameters() const params = api.getCompilerParameters()
const optimize = params.optimize const optimize = params.optimize
@ -84,6 +121,8 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
hideWarnings: hideWarnings, hideWarnings: hideWarnings,
autoCompile: autocompile, autoCompile: autocompile,
includeNightlies: includeNightlies, includeNightlies: includeNightlies,
useFileConfiguration: useFileConfiguration,
configFilePath: configFilePath,
optimize: optimize, optimize: optimize,
runs: runs, runs: runs,
evmVersion: (evmVersion !== null) && (evmVersion !== 'null') && (evmVersion !== undefined) && (evmVersion !== 'undefined') ? evmVersion : 'default', evmVersion: (evmVersion !== null) && (evmVersion !== 'null') && (evmVersion !== undefined) && (evmVersion !== 'undefined') ? evmVersion : 'default',
@ -140,12 +179,67 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
} }
}, [compilerContainer.editor.mode]) }, [compilerContainer.editor.mode])
useEffect(() => {
compileTabLogic.setUseFileConfiguration(state.useFileConfiguration)
if (state.useFileConfiguration) compileTabLogic.setConfigFilePath(state.configFilePath)
}, [state.useFileConfiguration])
useEffect(() => { useEffect(() => {
if (configurationSettings) { if (configurationSettings) {
setConfiguration(configurationSettings) setConfiguration(configurationSettings)
} }
}, [configurationSettings]) }, [configurationSettings])
const toggleConfigType = () => {
setState(prevState => {
api.setAppParameter('useFileConfiguration', !state.useFileConfiguration)
return { ...prevState, useFileConfiguration: !state.useFileConfiguration }
})
}
const openFile = async () => {
api.open(state.configFilePath)
}
const createNewConfigFile = async () => {
let filePath = configFilePathInput.current && configFilePathInput.current.value !== '' ? configFilePathInput.current.value : state.configFilePath
if (!filePath.endsWith('.json')) filePath = filePath + '.json'
await api.writeFile(filePath, configFileContent)
api.setAppParameter('configFilePath', filePath)
setState(prevState => {
return { ...prevState, configFilePath: filePath }
})
compileTabLogic.setConfigFilePath(filePath)
setShowFilePathInput(false)
}
const handleConfigPathChange = async () => {
if (configFilePathInput.current.value !== '') {
if (!configFilePathInput.current.value.endsWith('.json')) configFilePathInput.current.value += '.json'
if (await api.fileExists(configFilePathInput.current.value)) {
api.setAppParameter('configFilePath', configFilePathInput.current.value)
setState(prevState => {
return { ...prevState, configFilePath: configFilePathInput.current.value }
})
compileTabLogic.setConfigFilePath(configFilePathInput.current.value)
setShowFilePathInput(false)
} else {
modal(
'New configuration file', `The file "${configFilePathInput.current.value}" you entered does not exist. Do you want to create a new one?`,
'Create',
async () => await createNewConfigFile(),
'Cancel',
() => {
setShowFilePathInput(false)
}
)
}
}
}
const _retrieveVersion = (version?) => { const _retrieveVersion = (version?) => {
if (!version) version = state.selectedVersion if (!version) version = state.selectedVersion
if (version === 'builtin') version = state.defaultVersion if (version === 'builtin') version = state.defaultVersion
@ -538,14 +632,18 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
onChangeRuns(settings.runs) onChangeRuns(settings.runs)
} }
const toggleConfigurations = () => {
setToggleExpander(!toggleExpander)
}
return ( return (
<section> <section>
<article> <article>
<header className='remixui_compilerSection border-bottom'> <div className='pt-0 remixui_compilerSection'>
<div className="mb-2"> <div className="mb-1">
<label className="remixui_compilerLabel form-check-label" htmlFor="versionSelector"> <label className="remixui_compilerLabel form-check-label" htmlFor="versionSelector">
Compiler Compiler
<button className="far fa-plus-square border-0 p-0 mx-2 btn-sm" onClick={promptCompiler} title="Add a custom compiler with URL"></button> <button className="far fa-plus btn-light border-0 p-0 mx-2 btn-sm" onClick={promptCompiler} title="Add a custom compiler with URL"></button>
</label> </label>
<select value={ state.selectedVersion || state.defaultVersion } onChange={(e) => handleLoadVersion(e.target.value) } className="custom-select" id="versionSelector" disabled={state.allversions.length <= 0}> <select value={ state.selectedVersion || state.defaultVersion } onChange={(e) => handleLoadVersion(e.target.value) } className="custom-select" id="versionSelector" disabled={state.allversions.length <= 0}>
{ state.allversions.length <= 0 && <option disabled data-id={state.selectedVersion === state.defaultVersion ? 'selected' : ''}>{ state.defaultVersion }</option> } { state.allversions.length <= 0 && <option disabled data-id={state.selectedVersion === state.defaultVersion ? 'selected' : ''}>{ state.defaultVersion }</option> }
@ -559,51 +657,18 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
} }
</select> </select>
</div> </div>
<div className="mb-2 remixui_nightlyBuilds custom-control custom-checkbox"> <div className="mb-2 flex-row-reverse remixui_nightlyBuilds custom-control custom-checkbox">
<input className="mr-2 custom-control-input" id="nightlies" type="checkbox" onChange={handleNightliesChange} checked={state.includeNightlies} /> <input className="mr-2 custom-control-input" id="nightlies" type="checkbox" onChange={handleNightliesChange} checked={state.includeNightlies} />
<label htmlFor="nightlies" data-id="compilerNightliesBuild" className="form-check-label custom-control-label">Include nightly builds</label> <label htmlFor="nightlies" data-id="compilerNightliesBuild" className="form-check-label custom-control-label">Include nightly builds</label>
</div> </div>
<div className="mb-2">
<label className="remixui_compilerLabel form-check-label" htmlFor="compilierLanguageSelector">Language</label>
<select onChange={(e) => handleLanguageChange(e.target.value)} value={state.language} className="custom-select" id="compilierLanguageSelector" title="Available since v0.5.7">
<option data-id={state.language === 'Solidity' ? 'selected' : ''} value='Solidity'>Solidity</option>
<option data-id={state.language === 'Yul' ? 'selected' : ''} value='Yul'>Yul</option>
</select>
</div>
<div className="mb-2">
<label className="remixui_compilerLabel form-check-label" htmlFor="evmVersionSelector">EVM Version</label>
<select value={state.evmVersion} onChange={(e) => handleEvmVersionChange(e.target.value)} className="custom-select" id="evmVersionSelector">
{compileTabLogic.evmVersions.map((version, index) => (<option key={index} data-id={state.evmVersion === version ? 'selected' : ''} value={version}>{version}</option>))}
</select>
</div>
<div className="mt-3">
<p className="mt-2 remixui_compilerLabel">Compiler Configuration</p>
<div className="mt-2 remixui_compilerConfig custom-control custom-checkbox"> <div className="mt-2 remixui_compilerConfig custom-control custom-checkbox">
<input className="remixui_autocompile custom-control-input" type="checkbox" onChange={handleAutoCompile} data-id="compilerContainerAutoCompile" id="autoCompile" title="Auto compile" checked={state.autoCompile} /> <input className="remixui_autocompile custom-control-input" type="checkbox" onChange={handleAutoCompile} data-id="compilerContainerAutoCompile" id="autoCompile" title="Auto compile" checked={state.autoCompile} />
<label className="form-check-label custom-control-label" htmlFor="autoCompile">Auto compile</label> <label className="form-check-label custom-control-label" htmlFor="autoCompile">Auto compile</label>
</div> </div>
<div className="mt-2 remixui_compilerConfig custom-control custom-checkbox"> <div className="mt-1 mb-2 remixui_compilerConfig custom-control custom-checkbox">
<div className="justify-content-between align-items-center d-flex">
<input onChange={(e) => { handleOptimizeChange(e.target.checked) }} className="custom-control-input" id="optimize" type="checkbox" checked={state.optimize} />
<label className="form-check-label custom-control-label" htmlFor="optimize">Enable optimization</label>
<input
min="1"
className="custom-select ml-2 remixui_runs"
id="runs"
placeholder="200"
value={state.runs}
type="number"
title="Estimated number of times each opcode of the deployed code will be executed across the life-time of the contract."
onChange={(e) => onChangeRuns(e.target.value)}
disabled={!state.optimize}
/>
</div>
</div>
<div className="mt-2 remixui_compilerConfig custom-control custom-checkbox">
<input className="remixui_autocompile custom-control-input" onChange={handleHideWarningsChange} id="hideWarningsBox" type="checkbox" title="Hide warnings" checked={state.hideWarnings} /> <input className="remixui_autocompile custom-control-input" onChange={handleHideWarningsChange} id="hideWarningsBox" type="checkbox" title="Hide warnings" checked={state.hideWarnings} />
<label className="form-check-label custom-control-label" htmlFor="hideWarningsBox">Hide warnings</label> <label className="form-check-label custom-control-label" htmlFor="hideWarningsBox">Hide warnings</label>
</div> </div>
</div>
{ {
isHardhatProject && isHardhatProject &&
<div className="mt-3 remixui_compilerConfig custom-control custom-checkbox"> <div className="mt-3 remixui_compilerConfig custom-control custom-checkbox">
@ -636,7 +701,81 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
</a> </a>
</div> </div>
} }
</div>
<div className="d-flex px-4 remixui_compilerConfigSection justify-content-between" onClick={toggleConfigurations}>
<div className="d-flex">
<label className="mt-1 remixui_compilerConfigSection">Advanced Configurations</label>
</div>
<div> <div>
<span data-id='scConfigExpander' onClick={toggleConfigurations}>
<i className={!toggleExpander ? 'fas fa-angle-right' : 'fas fa-angle-down'} aria-hidden="true"></i>
</span>
</div>
</div>
<div className={`px-4 pb-4 border-bottom flex-column ${toggleExpander ? "d-flex" : "d-none"}`}>
<div className="d-flex pb-1 remixui_compilerConfig custom-control custom-radio">
<input className="custom-control-input" type="radio" name="configradio" value="manual" onChange={toggleConfigType} checked={!state.useFileConfiguration} id="scManualConfig" />
<label className="form-check-label custom-control-label" htmlFor="scManualConfig">Compiler configuration</label>
</div>
<div className={`flex-column 'd-flex'}`}>
<div className="mb-2 ml-4">
<label className="remixui_compilerLabel form-check-label" htmlFor="compilierLanguageSelector">Language</label>
<select onChange={(e) => handleLanguageChange(e.target.value)} disabled={state.useFileConfiguration} value={state.language} className="custom-select" id="compilierLanguageSelector" title="Available since v0.5.7">
<option data-id={state.language === 'Solidity' ? 'selected' : ''} value='Solidity'>Solidity</option>
<option data-id={state.language === 'Yul' ? 'selected' : ''} value='Yul'>Yul</option>
</select>
</div>
<div className="mb-2 ml-4">
<label className="remixui_compilerLabel form-check-label" htmlFor="evmVersionSelector">EVM Version</label>
<select value={state.evmVersion} onChange={(e) => handleEvmVersionChange(e.target.value)} disabled={state.useFileConfiguration} className="custom-select" id="evmVersionSelector">
{compileTabLogic.evmVersions.map((version, index) => (<option key={index} data-id={state.evmVersion === version ? 'selected' : ''} value={version}>{version}</option>))}
</select>
</div>
<div className="mt-1 mt-3 border-dark pb-3 ml-4 remixui_compilerConfig custom-control custom-checkbox">
<div className="justify-content-between align-items-center d-flex">
<input onChange={(e) => { handleOptimizeChange(e.target.checked) }} disabled={state.useFileConfiguration} className="custom-control-input" id="optimize" type="checkbox" checked={state.optimize} />
<label className="form-check-label custom-control-label" htmlFor="optimize">Enable optimization</label>
<input
min="1"
className="custom-select ml-2 remixui_runs"
id="runs"
placeholder="200"
value={state.runs}
type="number"
title="Estimated number of times each opcode of the deployed code will be executed across the life-time of the contract."
onChange={(e) => onChangeRuns(e.target.value)}
disabled={!state.optimize || state.useFileConfiguration}
/>
</div>
</div>
</div>
<div className="d-flex pb-1 remixui_compilerConfig custom-control custom-radio">
<input className="custom-control-input" type="radio" name="configradio" value="file" onChange={toggleConfigType} checked={state.useFileConfiguration} id="scFileConfig" />
<label className="form-check-label custom-control-label" htmlFor="scFileConfig">Use configuration file</label>
</div>
<div className={`pt-2 ml-4 ml-2 align-items-start justify-content-between d-flex`}>
{ (!showFilePathInput && state.useFileConfiguration) && <span
title="Click to open the config file."
onClick={openFile}
className="py-2 text-primary remixui_compilerConfigPath"
>{state.configFilePath}</span> }
{ (!showFilePathInput&& !state.useFileConfiguration) && <span className="py-2 text-secondary">{state.configFilePath}</span> }
<input
ref={configFilePathInput}
className={`py-0 my-0 form-control ${showFilePathInput ? "d-flex" : "d-none"}`}
placeholder={"Enter the new path"}
title="If the file you entered does not exist you will be able to create one in the next step."
disabled={!state.useFileConfiguration}
onKeyPress={event => {
if (event.key === 'Enter') {
handleConfigPathChange()
}
}}
/>
{ !showFilePathInput && <button disabled={!state.useFileConfiguration} className="btn-secondary" onClick={() => {setShowFilePathInput(true)}}>Change</button> }
</div>
</div>
<div className="px-4">
<button id="compileBtn" data-id="compilerContainerCompileBtn" className="btn btn-primary btn-block d-block w-100 text-break remixui_disabled mb-1 mt-3" onClick={compile} disabled={disableCompileButton}> <button id="compileBtn" data-id="compilerContainerCompileBtn" className="btn btn-primary btn-block d-block w-100 text-break remixui_disabled mb-1 mt-3" onClick={compile} disabled={disableCompileButton}>
<OverlayTrigger overlay={ <OverlayTrigger overlay={
<Tooltip id="overlay-tooltip-compile"> <Tooltip id="overlay-tooltip-compile">
@ -692,7 +831,6 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
</CopyToClipboard> </CopyToClipboard>
</div> </div>
</div> </div>
</header>
</article> </article>
</section> </section>
) )

@ -0,0 +1,18 @@
export const configFileContent = `
{
"language": "Solidity",
"settings": {
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"": ["ast"],
"*": ["abi", "metadata", "devdoc", "userdoc", "storageLayout", "evm.legacyAssembly", "evm.bytecode", "evm.deployedBytecode", "evm.methodIdentifiers", "evm.gasEstimates", "evm.assembly"]
}
},
"evmVersion": "byzantium"
}
}
`

@ -72,6 +72,15 @@
.remixui_compilerSection { .remixui_compilerSection {
padding: 12px 24px 16px; padding: 12px 24px 16px;
} }
.remixui_compilerConfigSection:hover {
cursor: pointer;
}
.remixui_compilerConfigSection {
font-size: 1rem;
}
.remixui_compilerConfigPath {
cursor: pointer;
}
.remixui_compilerLabel { .remixui_compilerLabel {
margin-bottom: 2px; margin-bottom: 2px;
font-size: 11px; font-size: 11px;

@ -18,6 +18,8 @@ export class CompileTabLogic {
public compilerImport public compilerImport
public event public event
public evmVersions: Array<string> public evmVersions: Array<string>
public useFileConfiguration: boolean
public configFilePath: string
constructor (public api: ICompilerApi, public contentImport) { constructor (public api: ICompilerApi, public contentImport) {
this.event = new EventEmitter() this.event = new EventEmitter()
@ -52,12 +54,21 @@ export class CompileTabLogic {
} }
} }
setOptimize (newOptimizeValue) { setOptimize (newOptimizeValue: boolean) {
this.optimize = newOptimizeValue this.optimize = newOptimizeValue
this.api.setCompilerParameters({ optimize: this.optimize }) this.api.setCompilerParameters({ optimize: this.optimize })
this.compiler.set('optimize', this.optimize) this.compiler.set('optimize', this.optimize)
} }
setUseFileConfiguration (useFileConfiguration: boolean) {
this.useFileConfiguration = useFileConfiguration
this.compiler.set('useFileConfiguration', useFileConfiguration)
}
setConfigFilePath (path) {
this.configFilePath = path
}
setRuns (runs) { setRuns (runs) {
this.runs = runs this.runs = runs
this.api.setCompilerParameters({ runs: this.runs }) this.api.setCompilerParameters({ runs: this.runs })
@ -95,6 +106,9 @@ export class CompileTabLogic {
const sources = { [target]: { content } } const sources = { [target]: { content } }
this.event.emit('removeAnnotations') this.event.emit('removeAnnotations')
this.event.emit('startingCompilation') this.event.emit('startingCompilation')
this.api.readFile(this.configFilePath).then( contentConfig => {
this.compiler.set('configFileContent', contentConfig)
})
// setTimeout fix the animation on chrome... (animation triggered by 'staringCompilation') // setTimeout fix the animation on chrome... (animation triggered by 'staringCompilation')
setTimeout(() => { this.compiler.compile(sources, target); resolve(true) }, 100) setTimeout(() => { this.compiler.compile(sources, target); resolve(true) }, 100)
}).catch((error) => { }).catch((error) => {

@ -13,6 +13,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
const [state, setState] = useState({ const [state, setState] = useState({
isHardhatProject: false, isHardhatProject: false,
isTruffleProject: false, isTruffleProject: false,
workspaceName: '',
currentFile, currentFile,
loading: false, loading: false,
compileTabLogic: null, compileTabLogic: null,
@ -63,11 +64,11 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
}) })
} }
api.onSetWorkspace = async (isLocalhost: boolean) => { api.onSetWorkspace = async (isLocalhost: boolean, workspaceName: string) => {
const isHardhat = isLocalhost && await compileTabLogic.isHardhatProject() const isHardhat = isLocalhost && await compileTabLogic.isHardhatProject()
const isTruffle = await compileTabLogic.isTruffleProject() const isTruffle = await compileTabLogic.isTruffleProject()
setState(prevState => { setState(prevState => {
return { ...prevState, currentFile, isHardhatProject: isHardhat, isTruffleProject: isTruffle } return { ...prevState, currentFile, isHardhatProject: isHardhat, workspaceName: workspaceName, isTruffleProject: isTruffle }
}) })
} }
@ -150,7 +151,18 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
return ( return (
<> <>
<div id="compileTabView"> <div id="compileTabView">
<CompilerContainer api={api} isHardhatProject={state.isHardhatProject} isTruffleProject={state.isTruffleProject} compileTabLogic={compileTabLogic} tooltip={toast} modal={modal} compiledFileName={currentFile} updateCurrentVersion={updateCurrentVersion} configurationSettings={configurationSettings} /> <CompilerContainer
api={api}
isHardhatProject={state.isHardhatProject}
workspaceName={state.workspaceName}
isTruffleProject={state.isTruffleProject}
compileTabLogic={compileTabLogic}
tooltip={toast}
modal={modal}
compiledFileName={currentFile}
updateCurrentVersion={updateCurrentVersion}
configurationSettings={configurationSettings}
/>
{ contractsFile[currentFile] && contractsFile[currentFile].contractsDetails && <ContractSelection api={api} contractsDetails={contractsFile[currentFile].contractsDetails} contractList={contractsFile[currentFile].contractList} modal={modal} /> } { contractsFile[currentFile] && contractsFile[currentFile].contractsDetails && <ContractSelection api={api} contractsDetails={contractsFile[currentFile].contractsDetails} contractList={contractsFile[currentFile].contractList} modal={modal} /> }
{ compileErrors[currentFile] && { compileErrors[currentFile] &&
<div className="remixui_errorBlobs p-4" data-id="compiledErrors"> <div className="remixui_errorBlobs p-4" data-id="compiledErrors">

@ -11,6 +11,7 @@ export interface CompilerContainerProps {
compileTabLogic: CompileTabLogic, compileTabLogic: CompileTabLogic,
isHardhatProject: boolean, isHardhatProject: boolean,
isTruffleProject: boolean, isTruffleProject: boolean,
workspaceName: string,
tooltip: (message: string | JSX.Element) => void, tooltip: (message: string | JSX.Element) => void,
modal: (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => void, modal: (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => void,
compiledFileName: string, compiledFileName: string,
@ -45,4 +46,3 @@ export interface CompilationDetails {
export interface ContractsFile { export interface ContractsFile {
[currentFile: string]: CompilationDetails [currentFile: string]: CompilationDetails
} }

@ -4,7 +4,7 @@
"jsx": "react", "jsx": "react",
"allowJs": true, "allowJs": true,
"esModuleInterop": true, "esModuleInterop": true,
"allowSyntheticDefaultImports": true "allowSyntheticDefaultImports": true,
}, },
"files": [], "files": [],
"include": [], "include": [],

@ -10,7 +10,7 @@ export interface TabsUIProps {
onZoomOut: () => void onZoomOut: () => void
onZoomIn: () => void onZoomIn: () => void
onReady: (api: any) => void onReady: (api: any) => void
themeQuality: "dark" themeQuality: string
} }
export interface TabsUIApi { export interface TabsUIApi {

@ -7,7 +7,7 @@ export const TreeView = (props: TreeViewProps) => {
const { children, id, ...otherProps } = props const { children, id, ...otherProps } = props
return ( return (
<ul data-id={`treeViewUl${id}`} className="ul_tv ml-0 px-2" { ...otherProps }> <ul data-id={`treeViewUl${id}`} className="ul_tv ml-0 pl-2" { ...otherProps }>
{ children } { children }
</ul> </ul>
) )

@ -57,7 +57,7 @@ export const FileLabel = (props: FileLabelProps) => {
> >
<span <span
title={file.path} title={file.path}
className={'remixui_label ' + (file.isDirectory ? 'folder' : 'remixui_leaf')} className={'text-nowrap remixui_label ' + (file.isDirectory ? 'folder' : 'remixui_leaf')}
data-path={file.path} data-path={file.path}
> >
{ file.name } { file.name }

@ -134,6 +134,8 @@ export function Workspace () {
<option value='remixDefault'>Default</option> <option value='remixDefault'>Default</option>
<option value='blank'>Blank</option> <option value='blank'>Blank</option>
<option value='ozerc20'>OpenZeppelin ERC20</option> <option value='ozerc20'>OpenZeppelin ERC20</option>
<option value='zeroxErc20'>0xProject ERC20</option>
<option value='ozerc721'>OpenZeppelin ERC721</option>
</select> </select>
</> </>
) )
@ -191,7 +193,7 @@ export function Workspace () {
title='Delete'> title='Delete'>
</span> </span>
<span <span
hidden={currentWorkspace === NO_WORKSPACE} hidden={currentWorkspace === LOCALHOST || currentWorkspace === NO_WORKSPACE}
id='workspacesDownload' id='workspacesDownload'
data-id='workspacesDownload' data-id='workspacesDownload'
onClick={(e) => { onClick={(e) => {
@ -202,6 +204,7 @@ export function Workspace () {
title='Download Workspaces'> title='Download Workspaces'>
</span> </span>
<span <span
hidden={currentWorkspace === LOCALHOST}
id='workspacesRestore' id='workspacesRestore'
data-id='workspacesRestore' data-id='workspacesRestore'
onClick={(e) => { onClick={(e) => {

@ -12,7 +12,7 @@
`@remix-project/remix-url-resolver` is an NPM package and can be installed using NPM as: `@remix-project/remix-url-resolver` is an NPM package and can be installed using NPM as:
`npm install @remix-project/remix-url-resolver` `yarn add @remix-project/remix-url-resolver`
### How to use ### How to use

@ -8,7 +8,7 @@
`@remix-project/remix-ws-templates` is an NPM package and can be installed using NPM as: `@remix-project/remix-ws-templates` is an NPM package and can be installed using NPM as:
`npm install @remix-project/remix-ws-templates` `yarn add @remix-project/remix-ws-templates`
### Contribute ### Contribute

@ -1,3 +1,5 @@
export { default as remixDefault } from './templates/remixDefault' export { default as remixDefault } from './templates/remixDefault'
export { default as ozerc20 } from './templates/ozerc20'
export { default as blank } from './templates/blank' export { default as blank } from './templates/blank'
export { default as ozerc20 } from './templates/ozerc20'
export { default as zeroxErc20 } from './templates/zeroxErc20'
export { default as ozerc721 } from './templates/ozerc721'

@ -3,13 +3,13 @@ export default async () => {
// @ts-ignore // @ts-ignore
'contracts/SampleERC20.sol': (await import('raw-loader!./contracts/SampleERC20.sol')).default, 'contracts/SampleERC20.sol': (await import('raw-loader!./contracts/SampleERC20.sol')).default,
// @ts-ignore // @ts-ignore
'scripts/deploy_with_ethers.ts': (await import('raw-loader!./scripts/deploy_with_ethers.ts')).default, 'scripts/deploy_with_ethers.ts': (await import('!!raw-loader!./scripts/deploy_with_ethers.ts')).default,
// @ts-ignore // @ts-ignore
'scripts/deploy_with_web3.ts': (await import('raw-loader!./scripts/deploy_with_web3.ts')).default, 'scripts/deploy_with_web3.ts': (await import('!!raw-loader!./scripts/deploy_with_web3.ts')).default,
// @ts-ignore // @ts-ignore
'scripts/ethers-lib.ts': (await import('raw-loader!./scripts/ethers-lib.ts')).default, 'scripts/ethers-lib.ts': (await import('!!raw-loader!./scripts/ethers-lib.ts')).default,
// @ts-ignore // @ts-ignore
'scripts/web3-lib.ts': (await import('raw-loader!./scripts/web3-lib.ts')).default, 'scripts/web3-lib.ts': (await import('!!raw-loader!./scripts/web3-lib.ts')).default,
// @ts-ignore // @ts-ignore
'tests/SampleERC20_test.sol': (await import('raw-loader!./tests/SampleERC20_test.sol')).default 'tests/SampleERC20_test.sol': (await import('raw-loader!./tests/SampleERC20_test.sol')).default
} }

@ -1,4 +1,4 @@
import { ethers } from 'ethers-lib' import { ethers } from 'ethers'
export const deploy = async (contractName: string, args: Array<any>, from?: string): Promise<any> => { export const deploy = async (contractName: string, args: Array<any>, from?: string): Promise<any> => {

@ -1,4 +1,4 @@
import Web3 from 'web3-lib' import Web3 from 'web3'
export const deploy = async (contractName: string, args: Array<any>, from?: string, gas?: number): Promise<any> => { export const deploy = async (contractName: string, args: Array<any>, from?: string, gas?: number): Promise<any> => {

@ -0,0 +1,14 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
/**
* @title SampleERC721
* @dev Create a sample ERC721 standard token
*/
contract SampleERC721 is ERC721 {
constructor(string memory tokenName, string memory tokenSymbol) ERC721(tokenName, tokenSymbol) {}
}

@ -0,0 +1,16 @@
export default async () => {
return {
// @ts-ignore
'contracts/SampleERC721.sol': (await import('raw-loader!./contracts/SampleERC721.sol')).default,
// @ts-ignore
'scripts/deploy_with_ethers.ts': (await import('!!raw-loader!./scripts/deploy_with_ethers.ts')).default,
// @ts-ignore
'scripts/deploy_with_web3.ts': (await import('!!raw-loader!./scripts/deploy_with_web3.ts')).default,
// @ts-ignore
'scripts/ethers-lib.ts': (await import('!!raw-loader!./scripts/ethers-lib.ts')).default,
// @ts-ignore
'scripts/web3-lib.ts': (await import('!!raw-loader!./scripts/web3-lib.ts')).default,
// @ts-ignore
'tests/SampleERC721_test.sol': (await import('raw-loader!./tests/SampleERC721_test.sol')).default
}
}

@ -0,0 +1,10 @@
import { deploy } from './ethers-lib'
(async () => {
try {
const result = await deploy('SampleERC721', ['testNFT', 'TNFT'])
console.log(`address: ${result.address}`)
} catch (e) {
console.log(e.message)
}
})()

@ -0,0 +1,10 @@
import { deploy } from './web3-lib'
(async () => {
try {
const result = await deploy('SampleERC721', ['testToken', 'TST'])
console.log(`address: ${result.address}`)
} catch (e) {
console.log(e.message)
}
})()

@ -0,0 +1,26 @@
import { ethers } from 'ethers'
export const deploy = async (contractName: string, args: Array<any>, from?: string): Promise<any> => {
console.log(`deploying ${contractName}`)
// Note that the script needs the ABI which is generated from the compilation artifact.
// Make sure contract is compiled and artifacts are generated
const artifactsPath = `browser/contracts/artifacts/${contractName}.json`
const metadata = JSON.parse(await remix.call('fileManager', 'getFile', artifactsPath))
// 'web3Provider' is a remix global variable object
const signer = (new ethers.providers.Web3Provider(web3Provider)).getSigner()
const factory = new ethers.ContractFactory(metadata.abi, metadata.data.bytecode.object, signer);
let contract
if (from) {
contract = await factory.connect(from).deploy(...args);
} else {
contract = await factory.deploy(...args);
}
// The contract is NOT deployed yet; we must wait until it is mined
await contract.deployed()
return contract
}

@ -0,0 +1,27 @@
import Web3 from 'web3'
export const deploy = async (contractName: string, args: Array<any>, from?: string, gas?: number): Promise<any> => {
const web3 = new Web3(window.web3Provider)
console.log(`deploying ${contractName}`)
// Note that the script needs the ABI which is generated from the compilation artifact.
// Make sure contract is compiled and artifacts are generated
const artifactsPath = `browser/contracts/artifacts/${contractName}.json`
const metadata = JSON.parse(await remix.call('fileManager', 'getFile', artifactsPath))
const accounts = await web3.eth.getAccounts()
let contract = new web3.eth.Contract(metadata.abi)
contract = contract.deploy({
data: metadata.data.bytecode.object,
arguments: args
})
const newContractInstance = await contract.send({
from: from || accounts[0],
gas: gas || 1500000
})
return newContractInstance.options
}

@ -0,0 +1,18 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
import "remix_tests.sol";
import "../contracts/SampleERC721.sol";
contract SampleERC721Test {
SampleERC721 s;
function beforeAll () public {
s = new SampleERC721("TestNFT", "TNFT");
}
function testTokenNameAndSymbol () public {
Assert.equal(s.name(), "TestNFT", "token name did not match");
Assert.equal(s.symbol(), "TNFT", "token symbol did not match");
}
}

@ -7,17 +7,17 @@ export default async () => {
// @ts-ignore // @ts-ignore
'contracts/3_Ballot.sol': (await import('raw-loader!./contracts/3_Ballot.sol')).default, 'contracts/3_Ballot.sol': (await import('raw-loader!./contracts/3_Ballot.sol')).default,
// @ts-ignore // @ts-ignore
'scripts/deploy_with_ethers.ts': (await import('raw-loader!./scripts/deploy_with_ethers.ts')).default, 'scripts/deploy_with_ethers.ts': (await import('!!raw-loader!./scripts/deploy_with_ethers.ts')).default,
// @ts-ignore // @ts-ignore
'scripts/deploy_with_web3.ts': (await import('raw-loader!./scripts/deploy_with_web3.ts')).default, 'scripts/deploy_with_web3.ts': (await import('!!raw-loader!./scripts/deploy_with_web3.ts')).default,
// @ts-ignore // @ts-ignore
'scripts/ethers-lib.ts': (await import('raw-loader!./scripts/ethers-lib.ts')).default, 'scripts/ethers-lib.ts': (await import('!!raw-loader!./scripts/ethers-lib.ts')).default,
// @ts-ignore // @ts-ignore
'scripts/web3-lib.ts': (await import('raw-loader!./scripts/web3-lib.ts')).default, 'scripts/web3-lib.ts': (await import('!!raw-loader!./scripts/web3-lib.ts')).default,
// @ts-ignore // @ts-ignore
'tests/Ballot_test.sol': (await import('raw-loader!./tests/Ballot_test.sol')).default, 'tests/Ballot_test.sol': (await import('raw-loader!./tests/Ballot_test.sol')).default,
// @ts-ignore // @ts-ignore
'tests/storage.test.js': (await import('raw-loader!./tests/storage.test.js')).default, 'tests/storage.test.js': (await import('!!raw-loader!./tests/storage.test.js')).default,
// @ts-ignore // @ts-ignore
'README.txt': (await import('raw-loader!./README.txt')).default, 'README.txt': (await import('raw-loader!./README.txt')).default,
} }

@ -0,0 +1,31 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.5.9;
import "@0x/contracts-erc20/contracts/src/ERC20Token.sol";
/**
* @title SampleERC20
* @dev Create a sample ERC20 standard token
*/
contract SampleERC20 is ERC20Token {
string public name;
string public symbol;
uint256 public decimals;
constructor (
string memory _name,
string memory _symbol,
uint256 _decimals,
uint256 _totalSupply
)
public
{
name = _name;
symbol = _symbol;
decimals = _decimals;
_totalSupply = _totalSupply;
balances[msg.sender] = _totalSupply;
}
}

@ -0,0 +1,16 @@
export default async () => {
return {
// @ts-ignore
'contracts/SampleERC20.sol': (await import('raw-loader!./contracts/SampleERC20.sol')).default,
// @ts-ignore
'scripts/deploy_with_ethers.ts': (await import('!!raw-loader!./scripts/deploy_with_ethers.ts')).default,
// @ts-ignore
'scripts/deploy_with_web3.ts': (await import('!!raw-loader!./scripts/deploy_with_web3.ts')).default,
// @ts-ignore
'scripts/ethers-lib.ts': (await import('!!raw-loader!./scripts/ethers-lib.ts')).default,
// @ts-ignore
'scripts/web3-lib.ts': (await import('!!raw-loader!./scripts/web3-lib.ts')).default,
// @ts-ignore
'tests/SampleERC20_test.sol': (await import('raw-loader!./tests/SampleERC20_test.sol')).default
}
}

@ -0,0 +1,10 @@
import { deploy } from './ethers-lib'
(async () => {
try {
const result = await deploy('SampleERC20', ["TestToken", "TST", 18, 1000])
console.log(`address: ${result.address}`)
} catch (e) {
console.log(e.message)
}
})()

@ -0,0 +1,10 @@
import { deploy } from './web3-lib'
(async () => {
try {
const result = await deploy('SampleERC20', ["TestToken", "TST", 18, 1000])
console.log(`address: ${result.address}`)
} catch (e) {
console.log(e.message)
}
})()

@ -0,0 +1,26 @@
import { ethers } from 'ethers'
export const deploy = async (contractName: string, args: Array<any>, from?: string): Promise<any> => {
console.log(`deploying ${contractName}`)
// Note that the script needs the ABI which is generated from the compilation artifact.
// Make sure contract is compiled and artifacts are generated
const artifactsPath = `browser/contracts/artifacts/${contractName}.json`
const metadata = JSON.parse(await remix.call('fileManager', 'getFile', artifactsPath))
// 'web3Provider' is a remix global variable object
const signer = (new ethers.providers.Web3Provider(web3Provider)).getSigner()
const factory = new ethers.ContractFactory(metadata.abi, metadata.data.bytecode.object, signer);
let contract
if (from) {
contract = await factory.connect(from).deploy(...args);
} else {
contract = await factory.deploy(...args);
}
// The contract is NOT deployed yet; we must wait until it is mined
await contract.deployed()
return contract
}

@ -0,0 +1,27 @@
import Web3 from 'web3'
export const deploy = async (contractName: string, args: Array<any>, from?: string, gas?: number): Promise<any> => {
const web3 = new Web3(window.web3Provider)
console.log(`deploying ${contractName}`)
// Note that the script needs the ABI which is generated from the compilation artifact.
// Make sure contract is compiled and artifacts are generated
const artifactsPath = `browser/contracts/artifacts/${contractName}.json`
const metadata = JSON.parse(await remix.call('fileManager', 'getFile', artifactsPath))
const accounts = await web3.eth.getAccounts()
let contract = new web3.eth.Contract(metadata.abi)
contract = contract.deploy({
data: metadata.data.bytecode.object,
arguments: args
})
const newContractInstance = await contract.send({
from: from || accounts[0],
gas: gas || 1500000
})
return newContractInstance.options
}

@ -0,0 +1,18 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.5.9;
import "remix_tests.sol";
import "../contracts/SampleERC20.sol";
contract SampleERC20Test {
SampleERC20 s;
function beforeAll () public {
s = new SampleERC20("TestToken", "TST", 18, 1000);
}
function testTokenNameAndSymbol () public {
Assert.equal(s.name(), "TestToken", "token name did not match");
Assert.equal(s.symbol(), "TST", "token symbol did not match");
}
}

@ -13,14 +13,14 @@ Alternatively `remixd` can be used to setup a development environment that can b
## INSTALLATION ## INSTALLATION
`npm install -g @remix-project/remixd` `yarn global add @remix-project/remixd`
### Warning for old users ### Warning for old users
There is a new version of remixd with a new npm address: https://npmjs.com/package/@remix-project/remixd There is a new version of remixd with a new npm address: https://npmjs.com/package/@remix-project/remixd
If you were using the old one you need to: If you were using the old one you need to:
1. uninstall the old one: `npm uninstall -g remixd` 1. uninstall the old one: `npm uninstall -g remixd`
2. install the new: `npm install -g @remix-project/remixd` 2. install the new: `yarn global add @remix-project/remixd`
## HELP SECTION ## HELP SECTION

@ -1,5 +1,5 @@
{ {
"watch": ["./src", "./bin"], "watch": ["./src", "./bin"],
"ext": "ts", "ext": "ts",
"exec": "npm run build && npm run start" "exec": "yarn run build && yarn run start"
} }

@ -18,7 +18,7 @@ async function warnLatestVersion () {
} else if (semver.gt(latest, pjson.version)) { } else if (semver.gt(latest, pjson.version)) {
console.log('\x1b[33m%s\x1b[0m', `[WARN] latest version of remixd is ${latest}, you are using ${pjson.version}`) console.log('\x1b[33m%s\x1b[0m', `[WARN] latest version of remixd is ${latest}, you are using ${pjson.version}`)
console.log('\x1b[33m%s\x1b[0m', '[WARN] please update using the following command:') console.log('\x1b[33m%s\x1b[0m', '[WARN] please update using the following command:')
console.log('\x1b[33m%s\x1b[0m', '[WARN] npm install @remix-project/remixd -g') console.log('\x1b[33m%s\x1b[0m', '[WARN] yarn global add @remix-project/remixd')
} }
} }

48108
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -48,11 +48,11 @@
"lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remix-ws-templates,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-helper,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox,remix-ui-settings,remix-core-plugin,remix-ui-renderer,remix-ui-publish-to-storage,remix-ui-solidity-compiler,solidity-unit-testing,remix-ui-plugin-manager,remix-ui-terminal,remix-ui-editor,remix-ui-app,remix-ui-tabs,remix-ui-panel,remix-ui-run-tab,remix-ui-permission-handler,remix-ui-search", "lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remix-ws-templates,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-helper,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox,remix-ui-settings,remix-core-plugin,remix-ui-renderer,remix-ui-publish-to-storage,remix-ui-solidity-compiler,solidity-unit-testing,remix-ui-plugin-manager,remix-ui-terminal,remix-ui-editor,remix-ui-app,remix-ui-tabs,remix-ui-panel,remix-ui-run-tab,remix-ui-permission-handler,remix-ui-search",
"build:libs": "nx run-many --target=build --parallel=false --with-deps=true --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remix-ws-templates,remixd", "build:libs": "nx run-many --target=build --parallel=false --with-deps=true --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remix-ws-templates,remixd",
"test:libs": "nx run-many --target=test --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd", "test:libs": "nx run-many --target=test --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd",
"publish:libs": "npm run build:libs && lerna publish --skip-git && npm run bumpVersion:libs", "publish:libs": "yarn run build:libs && lerna publish --skip-git && yarn run bumpVersion:libs",
"build:e2e": "node apps/remix-ide-e2e/src/buildGroupTests.js && tsc -p apps/remix-ide-e2e/tsconfig.e2e.json", "build:e2e": "node apps/remix-ide-e2e/src/buildGroupTests.js && tsc -p apps/remix-ide-e2e/tsconfig.e2e.json",
"watch:e2e": "nodemon", "watch:e2e": "nodemon",
"bumpVersion:libs": "gulp & gulp syncLibVersions;", "bumpVersion:libs": "gulp & gulp syncLibVersions;",
"browsertest": "sleep 5 && npm run nightwatch_local", "browsertest": "sleep 5 && yarn run nightwatch_local",
"csslint": "csslint --ignore=order-alphabetical --errors='errors,duplicate-properties,empty-rules' --exclude-list='apps/remix-ide/src/assets/css/font-awesome.min.css' apps/remix-ide/src/assets/css/", "csslint": "csslint --ignore=order-alphabetical --errors='errors,duplicate-properties,empty-rules' --exclude-list='apps/remix-ide/src/assets/css/font-awesome.min.css' apps/remix-ide/src/assets/css/",
"downloadsolc_assets": "wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.7+commit.e28d00a7.js -O ./apps/remix-ide/src/assets/js/soljson.js && wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.7+commit.e28d00a7.js -O ./apps/solidity-compiler/src/assets/js/soljson.js", "downloadsolc_assets": "wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.7+commit.e28d00a7.js -O ./apps/remix-ide/src/assets/js/soljson.js && wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.7+commit.e28d00a7.js -O ./apps/solidity-compiler/src/assets/js/soljson.js",
"downloadsolc_assets_dist": "wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.7+commit.e28d00a7.js -O ./dist/apps/remix-ide/assets/js/soljson.js && wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.7+commit.e28d00a7.js -O ./dist/apps/solidity-compiler/assets/js/soljson.js", "downloadsolc_assets_dist": "wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.7+commit.e28d00a7.js -O ./dist/apps/remix-ide/assets/js/soljson.js && wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.7+commit.e28d00a7.js -O ./dist/apps/solidity-compiler/assets/js/soljson.js",
@ -61,44 +61,44 @@
"build:production": "NODE_ENV=production nx build remix-ide --skip-nx-cache", "build:production": "NODE_ENV=production nx build remix-ide --skip-nx-cache",
"serve:production": "npx http-server ./dist/apps/remix-ide", "serve:production": "npx http-server ./dist/apps/remix-ide",
"select_test": "sh apps/remix-ide-e2e/src/select_tests.sh", "select_test": "sh apps/remix-ide-e2e/src/select_tests.sh",
"group_test": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/${npm_config_test}_group${npm_config_group}.test.js --env=${npm_config_env}", "group_test": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/${npm_config_test}_group${npm_config_group}.test.js --env=${npm_config_env}",
"nightwatch_parallel": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js --env=chrome,firefox", "nightwatch_parallel": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js --env=chrome,firefox",
"nightwatch_local_firefox": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js --env=firefox", "nightwatch_local_firefox": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js --env=firefox",
"nightwatch_local_chrome": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js --env=chrome", "nightwatch_local_chrome": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js --env=chrome",
"nightwatch_local_ballot": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/ballot.test.js --env=chrome", "nightwatch_local_ballot": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/ballot.test.js --env=chrome",
"nightwatch_local_ballot_0_4_11": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/ballot_0_4_11.test.js --env=chrome", "nightwatch_local_ballot_0_4_11": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/ballot_0_4_11.test.js --env=chrome",
"nightwatch_local_usingWorker": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/usingWebWorker.test.js --env=chrome", "nightwatch_local_usingWorker": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/usingWebWorker.test.js --env=chrome",
"nightwatch_local_libraryDeployment": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/libraryDeployment.test.js --env=chrome", "nightwatch_local_libraryDeployment": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/libraryDeployment.test.js --env=chrome",
"nightwatch_local_solidityImport": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/solidityImport_*.test.js --env=chrome", "nightwatch_local_solidityImport": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/solidityImport_*.test.js --env=chrome",
"nightwatch_local_recorder": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/recorder.test.js --env=chrome", "nightwatch_local_recorder": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/recorder.test.js --env=chrome",
"nightwatch_local_transactionExecution": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/transactionExecution_*.test.js --env=chrome", "nightwatch_local_transactionExecution": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/transactionExecution_*.test.js --env=chrome",
"nightwatch_local_staticAnalysis": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/staticAnalysis.test.js --env=chrome", "nightwatch_local_staticAnalysis": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/staticAnalysis.test.js --env=chrome",
"nightwatch_local_signingMessage": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/signingMessage.test.js --env=chrome", "nightwatch_local_signingMessage": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/signingMessage.test.js --env=chrome",
"nightwatch_local_specialFunctions": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/specialFunctions_*.test.js --env=chrome", "nightwatch_local_specialFunctions": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/specialFunctions_*.test.js --env=chrome",
"nightwatch_local_solidityUnitTests": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/solidityUnittests_*.test.js --env=chrome", "nightwatch_local_solidityUnitTests": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/solidityUnittests_*.test.js --env=chrome",
"nightwatch_local_remixd": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/remixd.test.js --env=chrome", "nightwatch_local_remixd": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/remixd.test.js --env=chrome",
"nightwatch_local_terminal": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/terminal_*.test.js --env=chrome", "nightwatch_local_terminal": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/terminal_*.test.js --env=chrome",
"nightwatch_local_gist": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/gist.test.js --env=chrome", "nightwatch_local_gist": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/gist.test.js --env=chrome",
"nightwatch_local_workspace": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/workspace.test.js --env=chrome", "nightwatch_local_workspace": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/workspace.test.js --env=chrome",
"nightwatch_local_defaultLayout": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/defaultLayout.test.js --env=chrome", "nightwatch_local_defaultLayout": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/defaultLayout.test.js --env=chrome",
"nightwatch_local_pluginManager": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/pluginManager.test.js --env=chrome", "nightwatch_local_pluginManager": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/pluginManager.test.js --env=chrome",
"nightwatch_local_publishContract": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/publishContract.test.js --env=chrome", "nightwatch_local_publishContract": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/publishContract.test.js --env=chrome",
"nightwatch_local_generalSettings": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/generalSettings.test.js --env=chrome", "nightwatch_local_generalSettings": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/generalSettings.test.js --env=chrome",
"nightwatch_local_fileExplorer": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/fileExplorer.test.js --env=chrome", "nightwatch_local_fileExplorer": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/fileExplorer.test.js --env=chrome",
"nightwatch_local_debugger": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/debugger_*.test.js --env=chrome", "nightwatch_local_debugger": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/debugger_*.test.js --env=chrome",
"nightwatch_local_editor": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/editor.test.js --env=chrome", "nightwatch_local_editor": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/editor.test.js --env=chrome",
"nightwatch_local_importFromGithub": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/importFromGithub.test.js --env=chrome", "nightwatch_local_importFromGithub": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/importFromGithub.test.js --env=chrome",
"nightwatch_local_compiler": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/compiler_api.test.js --env=chrome", "nightwatch_local_compiler": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/compiler_api.test.js --env=chrome",
"nightwatch_local_txListener": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/txListener.test.js --env=chrome", "nightwatch_local_txListener": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/txListener.test.js --env=chrome",
"nightwatch_local_fileManager": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/fileManager_api.test.js --env=chrome", "nightwatch_local_fileManager": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/fileManager_api.test.js --env=chrome",
"nightwatch_local_runAndDeploy": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/runAndDeploy.js --env=chrome-runAndDeploy", "nightwatch_local_runAndDeploy": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/runAndDeploy.js --env=chrome-runAndDeploy",
"nightwatch_local_url": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/url.test.js --env=chrome", "nightwatch_local_url": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/url.test.js --env=chrome",
"nightwatch_local_verticalIconscontextmenu": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/verticalIconsPanel.test.js --env=chrome", "nightwatch_local_verticalIconscontextmenu": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/verticalIconsPanel.test.js --env=chrome",
"nightwatch_local_pluginApi": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/plugin_api_*.js --env=chrome", "nightwatch_local_pluginApi": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/plugin_api_*.js --env=chrome",
"nightwatch_local_migrate_filesystem": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/migrateFileSystem.test.js --env=chrome", "nightwatch_local_migrate_filesystem": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/migrateFileSystem.test.js --env=chrome",
"nightwatch_local_stress_editor": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/stressEditor.test.js --env=chromeDesktop", "nightwatch_local_stress_editor": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/stressEditor.test.js --env=chromeDesktop",
"nightwatch_local_search": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/search.test.js --env=chromeDesktop", "nightwatch_local_search": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/search.test.js --env=chromeDesktop",
"nightwatch_local_providers": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/providers.test.js --env=chromeDesktop", "nightwatch_local_providers": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/providers.test.js --env=chromeDesktop",
"onchange": "onchange apps/remix-ide/build/app.js -- npm-run-all lint", "onchange": "onchange apps/remix-ide/build/app.js -- npm-run-all lint",
"remixd": "nx build remixd && chmod +x dist/libs/remixd/src/bin/remixd.js && dist/libs/remixd/src/bin/remixd.js -s ./apps/remix-ide/contracts --remix-ide http://127.0.0.1:8080", "remixd": "nx build remixd && chmod +x dist/libs/remixd/src/bin/remixd.js && dist/libs/remixd/src/bin/remixd.js -s ./apps/remix-ide/contracts --remix-ide http://127.0.0.1:8080",
"selenium": "selenium-standalone start", "selenium": "selenium-standalone start",
@ -106,7 +106,7 @@
"sourcemap": "exorcist --root ../ apps/remix-ide/build/app.js.map > apps/remix-ide/build/app.js", "sourcemap": "exorcist --root ../ apps/remix-ide/build/app.js.map > apps/remix-ide/build/app.js",
"test-browser": "npm-run-all -lpr selenium make-mock-compiler serve browsertest", "test-browser": "npm-run-all -lpr selenium make-mock-compiler serve browsertest",
"watch": "watchify apps/remix-ide/src/index.js -dv -p browserify-reload -o apps/remix-ide/build/app.js --exclude solc", "watch": "watchify apps/remix-ide/src/index.js -dv -p browserify-reload -o apps/remix-ide/build/app.js --exclude solc",
"reinstall": "rm ./node-modules/ -rf && rm package-lock.json && rm ./build/ -rf && npm install & npm run build", "reinstall": "rm ./node-modules/ -rf && rm package-lock.json && rm ./build/ -rf && yarn install & yarn run build",
"ganache-cli": "npx ganache-cli" "ganache-cli": "npx ganache-cli"
}, },
"browserify": { "browserify": {

@ -64,6 +64,42 @@ The release manager is still responsible for ensuring a project is rolled out sm
- During feature freeze, remix-beta should be updated every morning. - During feature freeze, remix-beta should be updated every morning.
- A meeting with Andy and Rob should be organized for ensuring the beta test results are properly handled. - A meeting with Andy and Rob should be organized for ensuring the beta test results are properly handled.
## check list:
### pre release planning
- [ ] create a new project and prioritize issues / bugs with the team lead and according to the current roadmap.
- [ ] check with the team lead if this needs an intermediate release (intermediate release should be 2-3 weeks max).
- [ ] a release kickoff meeting with the team aiming to get input from everyone and modify the project accordingly.
- [ ] 2-3 days span where team members estimate their issues.
- [ ] a release planning meeting where we agree on the release scope (intermediate and/or classic release).
- [ ] after this meeting: all the issues / PR should have been qualified in term of effort and scope.
- [ ] after this meeting: date for feature freeze, QA period, and release date should be set in the project title.
### coding period
- [ ] 10 min after each daily standup where the release manager give an update of the current situation and ETA.
- [ ] release manager should make sure to be aware of the current state of each issues and PRs during the coding period in order to have a better overview of who is working on what and best provide support to all the team members that are involved in the release.
### QA preparation
- [ ] prepare the internal QA document, assign team members.
- [ ] prepare the external beta test document for beta testers.
- [ ] 1 week before QA period, start engaging with beta testers and online.
### feature freeze, QA period.
- [ ] publish to remix-beta every day.
- [ ] merge reviewed PRs.
- [ ] a QA open sync meeting where we all do our assigned tasks.
### post release
- [ ] retrospective meeting.
## Assignments: ## Assignments:
Aniket, Liana, David, Rob, Filip, Yann Aniket, Liana, David, Rob, Filip, Yann

@ -20,7 +20,7 @@ This document includes:
- git fetch origin master - git fetch origin master
- git checkout origin/master - git checkout origin/master
- git checkout -b bumpLibsVersion - git checkout -b bumpLibsVersion
- npm run publish:libs (this command uses lerna) - yarn run publish:libs (this command uses lerna)
- commit - commit
## Remix IDE release Part 1. First push master to beta. Feature Freeze ## Remix IDE release Part 1. First push master to beta. Feature Freeze

24426
yarn.lock

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save