Merge pull request #2868 from ethereum/optimizecircle

optimize circleCI
pull/2923/head
bunsenstraat 2 years ago committed by GitHub
commit 34579fff84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 498
      .circleci/config.yml
  2. 6
      apps/remix-ide-e2e/src/commands/addAtAddressInstance.ts
  3. 29
      apps/remix-ide-e2e/src/commands/addFile.ts
  4. 49
      apps/remix-ide-e2e/src/commands/checkVariableDebug.ts
  5. 5
      apps/remix-ide-e2e/src/commands/clickLaunchIcon.ts
  6. 5
      apps/remix-ide-e2e/src/commands/goToVMTraceStep.ts
  7. 16
      apps/remix-ide-e2e/src/commands/refreshPage.ts
  8. 16
      apps/remix-ide-e2e/src/commands/setSolidityCompilerVersion.ts
  9. 6
      apps/remix-ide-e2e/src/commands/switchWorkspace.ts
  10. 38
      apps/remix-ide-e2e/src/commands/verifyLoad.ts
  11. 36
      apps/remix-ide-e2e/src/helpers/init.ts
  12. 2
      apps/remix-ide-e2e/src/select_tests.sh
  13. 96
      apps/remix-ide-e2e/src/tests/ballot.test.ts
  14. 11
      apps/remix-ide-e2e/src/tests/ballot_0_4_14.test.ts
  15. 48
      apps/remix-ide-e2e/src/tests/debugger.test.ts
  16. 25
      apps/remix-ide-e2e/src/tests/erc721.test.ts
  17. 2
      apps/remix-ide-e2e/src/tests/fileExplorer.test.ts
  18. 2
      apps/remix-ide-e2e/src/tests/gist.test.ts
  19. 2
      apps/remix-ide-e2e/src/tests/migrateFileSystem.test.ts
  20. 2
      apps/remix-ide-e2e/src/tests/pluginManager.test.ts
  21. 51
      apps/remix-ide-e2e/src/tests/proxy.test.ts
  22. 2
      apps/remix-ide-e2e/src/tests/publishContract.test.ts
  23. 5
      apps/remix-ide-e2e/src/tests/recorder.test.ts
  24. 6
      apps/remix-ide-e2e/src/tests/runAndDeploy.test.ts
  25. 22
      apps/remix-ide-e2e/src/tests/solidityImport.test.ts
  26. 16
      apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts
  27. 2
      apps/remix-ide-e2e/src/tests/stressEditor.test.ts
  28. 2
      apps/remix-ide-e2e/src/tests/terminal.test.ts
  29. 2
      apps/remix-ide-e2e/src/tests/transactionExecution.test.ts
  30. 149
      apps/remix-ide-e2e/src/tests/url.test.ts
  31. 13
      apps/remix-ide-e2e/src/tests/usingWebWorker.test.ts
  32. 2
      apps/remix-ide-e2e/src/tests/workspace.test.ts
  33. 2
      apps/remix-ide-e2e/src/types/index.d.ts
  34. 3
      apps/remix-ide/.gitignore
  35. 9
      apps/remix-ide/ci/browser_test.sh
  36. 1
      apps/remix-ide/ci/browser_tests_etherscan_plugin.sh
  37. 1
      apps/remix-ide/ci/browser_tests_vyper_plugin.sh
  38. 63
      apps/remix-ide/ci/download_e2e_assets.js
  39. 27
      apps/remix-ide/ci/splice_tests.js
  40. 12
      apps/remix-ide/src/app.js
  41. 4
      libs/remix-ui/editor/src/lib/remix-ui-editor.tsx
  42. 4
      libs/remix-ui/editor/src/lib/web-types.ts
  43. 86
      libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx
  44. 3
      package.json

@ -1,7 +1,4 @@
# Javascript Node CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-javascript/ for more details
#
version: 2.1 version: 2.1
parameters: parameters:
run_flaky_tests: run_flaky_tests:
@ -9,28 +6,16 @@ parameters:
default: false default: false
orbs: orbs:
browser-tools: circleci/browser-tools@1.4.0 browser-tools: circleci/browser-tools@1.4.0
node: circleci/node@5.0.2
jobs: jobs:
build: build:
docker: docker:
# specify the version you desire here - image: cimg/node:14.17.6-browsers
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
resource_class: resource_class:
xlarge xlarge
# - image: circleci/mongo:3.4.4
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI"
working_directory: ~/remix-project working_directory: ~/remix-project
steps: steps:
- checkout - checkout
- node/install:
install-yarn: true
node-version: "v14.17.6"
- restore_cache: - restore_cache:
keys: keys:
- v1-deps-{{ checksum "yarn.lock" }} - v1-deps-{{ checksum "yarn.lock" }}
@ -39,37 +24,22 @@ jobs:
key: v1-deps-{{ checksum "yarn.lock" }} key: v1-deps-{{ checksum "yarn.lock" }}
paths: paths:
- node_modules - node_modules
- run: yarn run downloadsolc_assets - run: NX_BIN_URL=http://127.0.0.1:8080/assets/js NX_WASM_URL=http://127.0.0.1:8080/assets/js yarn build:production
- run: npx nx build remix-ide - run: npx nx build remix-ide-e2e-src-local-plugin & yarn run build:libs
- run: npx nx build remix-ide-e2e-src-local-plugin - run: mkdir persist && zip -0 -r persist/dist.zip dist
- run: yarn run build:libs
- run: mkdir persist && zip -r persist/dist.zip dist
- persist_to_workspace: - persist_to_workspace:
root: . root: .
paths: paths:
- "persist" - "persist"
lint: lint:
docker: docker:
# specify the version you desire here - image: cimg/node:14.17.6-browsers
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
resource_class: resource_class:
xlarge xlarge
# - image: circleci/mongo:3.4.4
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI"
working_directory: ~/remix-project working_directory: ~/remix-project
parallelism: 35 parallelism: 35
steps: steps:
- checkout - checkout
- node/install:
install-yarn: true
node-version: "v14.17.6"
- restore_cache: - restore_cache:
keys: keys:
- v1-deps-{{ checksum "yarn.lock" }} - v1-deps-{{ checksum "yarn.lock" }}
@ -79,25 +49,13 @@ jobs:
command: ./apps/remix-ide/ci/lint.sh command: ./apps/remix-ide/ci/lint.sh
remix-libs: remix-libs:
docker: docker:
# specify the version you desire here - image: cimg/node:14.17.6-browsers
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
resource_class: resource_class:
xlarge xlarge
# - image: circleci/mongo:3.4.4
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI"
working_directory: ~/remix-project working_directory: ~/remix-project
steps: steps:
- checkout - checkout
- node/install:
install-yarn: true
node-version: "v14.17.6"
- attach_workspace: - attach_workspace:
at: . at: .
- run: unzip ./persist/dist.zip - run: unzip ./persist/dist.zip
@ -108,368 +66,98 @@ jobs:
- run: cd dist/libs/remix-tests && yarn - run: cd dist/libs/remix-tests && yarn
- run: yarn run test:libs - run: yarn run test:libs
remix-ide-chrome: remix-ide-browser:
docker: docker:
# specify the version you desire here - image: cimg/node:14.17.6-browsers
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
resource_class: resource_class:
xlarge xlarge
# - image: circleci/mongo:3.4.4
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI"
working_directory: ~/remix-project working_directory: ~/remix-project
parameters:
parallelism: 95 browser:
type: string
script:
type: string
job:
type: string
jobsize:
type: string
parallelism: 10
steps: steps:
- node/install: - browser-tools/install-browser-tools
install-yarn: true
node-version: "v14.17.6"
- browser-tools/install-chrome
- browser-tools/install-chromedriver
- run: - run:
command: | command: |
google-chrome --version google-chrome --version
firefox --version
geckodriver --version
chromedriver --version chromedriver --version
name: Check install java -jar /usr/local/bin/selenium.jar --version
- checkout
- attach_workspace:
at: .
- run: unzip ./persist/dist.zip
- restore_cache:
keys:
- v1-deps-{{ checksum "yarn.lock" }}
- run: yarn
- run:
name: Java
command: sudo apt update && sudo apt install default-jre
- run:
name: Install Selenium
command: yarn run selenium-install
- run:
name: Run Selenium
command: yarn run selenium
background: true
- run: ./apps/remix-ide/ci/browser_test.sh chrome
- store_test_results:
path: ./reports/tests
- store_artifacts:
path: ./reports/screenshots
flaky-chrome:
docker:
# specify the version you desire here
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
resource_class:
xlarge
# - image: circleci/mongo:3.4.4
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI"
working_directory: ~/remix-project
parallelism: 95
steps:
- node/install:
install-yarn: true
node-version: "v14.17.6"
- browser-tools/install-chrome
- browser-tools/install-chromedriver
- run: - run:
name: Check out previous test metadata
command: | command: |
google-chrome --version cat "${CIRCLE_INTERNAL_TASK_DATA}/circle-test-results/results.json" | jq .
chromedriver --version ls -la "${CIRCLE_INTERNAL_TASK_DATA}/"
name: Check install
- checkout - checkout
- attach_workspace: - attach_workspace:
at: . at: .
- run: unzip ./persist/dist.zip - run: unzip ./persist/dist.zip
- restore_cache:
keys:
- v1-deps-{{ checksum "yarn.lock" }}
- run: yarn
- run:
name: Java
command: sudo apt update && sudo apt install default-jre
- run:
name: Install Selenium
command: yarn run selenium-install
- run:
name: Run Selenium
command: yarn run selenium
background: true
- run: ./apps/remix-ide/ci/flaky.sh chrome
- store_test_results:
path: ./reports/tests
- store_artifacts:
path: ./reports/screenshots
remix-ide-firefox:
docker:
# specify the version you desire here
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
resource_class:
xlarge
# - image: circleci/mongo:3.4.4
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI"
working_directory: ~/remix-project
parallelism: 95
steps:
- node/install:
install-yarn: true
node-version: "v14.17.6"
- browser-tools/install-firefox
- browser-tools/install-geckodriver
- run:
command: |
firefox --version
geckodriver --version
name: Check install
- checkout
- attach_workspace:
at: .
- run: unzip ./persist/dist.zip
- restore_cache: - restore_cache:
keys: keys:
- v1-deps-{{ checksum "yarn.lock" }} - v1-deps-{{ checksum "yarn.lock" }}
- run: yarn - run: yarn
- run: - run: yarn run downloadsolc_assets_e2e && yarn run downloadsolc_assets_dist
name: Java - run: ls -la ./dist/apps/remix-ide/assets/js
command: sudo apt update && sudo apt install default-jre
- run:
name: Install Selenium
command: yarn run selenium-install
- run: - run:
name: Run Selenium name: Start Selenium
command: yarn run selenium command: java -jar /usr/local/bin/selenium.jar
background: true background: true
- run: ./apps/remix-ide/ci/browser_test.sh firefox - run: ./apps/remix-ide/ci/<< parameters.script >> << parameters.browser >> << parameters.jobsize >> << parameters.job >>
- store_test_results: - store_test_results:
path: ./reports/tests path: ./reports/tests
- store_artifacts: - store_artifacts:
path: ./reports/screenshots path: ./reports/screenshots
flaky-firefox:
docker:
# specify the version you desire here
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
resource_class:
xlarge
# - image: circleci/mongo:3.4.4
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI"
working_directory: ~/remix-project
parallelism: 95 tests-passed:
machine:
image: ubuntu-2004:202010-01
steps: steps:
- node/install: - run: echo done
install-yarn: true
node-version: "v14.17.6"
- browser-tools/install-firefox
- browser-tools/install-geckodriver
- run:
command: |
firefox --version
geckodriver --version
name: Check install remix-test-plugins:
- checkout
- attach_workspace:
at: .
- run: unzip ./persist/dist.zip
- restore_cache:
keys:
- v1-deps-{{ checksum "yarn.lock" }}
- run: yarn
- run:
name: Java
command: sudo apt update && sudo apt install default-jre
- run:
name: Install Selenium
command: yarn run selenium-install
- run:
name: Run Selenium
command: yarn run selenium
background: true
- run: ./apps/remix-ide/ci/flaky.sh firefox
- store_test_results:
path: ./reports/tests
- store_artifacts:
path: ./reports/screenshots
remix-ide-vyper-plugin:
docker: docker:
# specify the version you desire here - image: cimg/node:14.17.6-browsers
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
resource_class: resource_class:
xlarge xlarge
# - image: circleci/mongo:3.4.4
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI"
working_directory: ~/remix-project working_directory: ~/remix-project
parameters:
script:
type: string
parallelism: 10 parallelism: 10
steps: steps:
- node/install: - browser-tools/install-browser-tools
install-yarn: true
node-version: "v14.17.6"
- browser-tools/install-chrome
- browser-tools/install-chromedriver
- run: - run:
command: | command: |
google-chrome --version google-chrome --version
firefox --version
geckodriver --version
chromedriver --version chromedriver --version
java -jar /usr/local/bin/selenium.jar --version
name: Check install name: Check install
- checkout - checkout
- attach_workspace: - attach_workspace:
at: . at: .
- run: unzip ./persist/dist.zip
- restore_cache:
keys:
- v1-deps-{{ checksum "yarn.lock" }}
- run: yarn
- run:
name: Java
command: sudo apt update && sudo apt install default-jre
- run:
name: Install Selenium
command: yarn run selenium-install
- run:
name: Run Selenium
command: yarn run selenium
background: true
- run: npx nx build vyper
- run: ./apps/remix-ide/ci/browser_tests_vyper_plugin.sh
- store_test_results:
path: ./reports/tests
- store_artifacts:
path: ./reports/screenshots
remix-ide-etherscan-plugin:
docker:
# specify the version you desire here
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
resource_class:
xlarge
# - image: circleci/mongo:3.4.4
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI"
working_directory: ~/remix-project
parallelism: 10
steps:
- node/install:
install-yarn: true
node-version: "v14.17.6"
- browser-tools/install-chrome
- browser-tools/install-chromedriver
- run:
command: |
google-chrome --version
chromedriver --version
name: Check install
- checkout
- attach_workspace:
at: .
- run: unzip ./persist/dist.zip
- restore_cache: - restore_cache:
keys: keys:
- v1-deps-{{ checksum "yarn.lock" }} - v1-deps-{{ checksum "yarn.lock" }}
- run: yarn - run: yarn
- run:
name: Java
command: sudo apt update && sudo apt install default-jre
- run:
name: Install Selenium
command: yarn run selenium-install
- run:
name: Run Selenium
command: yarn run selenium
background: true
- run: npx nx build etherscan
- run: ./apps/remix-ide/ci/browser_tests_etherscan_plugin.sh
- store_test_results:
path: ./reports/tests
- store_artifacts:
path: ./reports/screenshots
remix-ide-plugin-api:
docker:
# specify the version you desire here
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
resource_class:
xlarge
# - image: circleci/mongo:3.4.4
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI"
working_directory: ~/remix-project
parallelism: 10
steps:
- node/install:
install-yarn: true
node-version: "v14.17.6"
- browser-tools/install-chrome
- browser-tools/install-chromedriver
- run:
command: |
google-chrome --version
chromedriver --version
name: Check install
- checkout
- attach_workspace:
at: .
- run: unzip ./persist/dist.zip - run: unzip ./persist/dist.zip
- restore_cache: - run: yarn run downloadsolc_assets_e2e && yarn run downloadsolc_assets_dist
keys:
- v1-deps-{{ checksum "yarn.lock" }}
- run: yarn
- run:
name: Java
command: sudo apt update && sudo apt install default-jre
- run:
name: Install Selenium
command: yarn run selenium-install
- run: - run:
name: Run Selenium name: Start Selenium
command: yarn run selenium command: java -jar /usr/local/bin/selenium.jar
background: true background: true
- run: ./apps/remix-ide/ci/browser_tests_plugin_api.sh - run: ./apps/remix-ide/ci/<< parameters.script >>
- store_test_results: - store_test_results:
path: ./reports/tests path: ./reports/tests
- store_artifacts: - store_artifacts:
@ -477,15 +165,10 @@ jobs:
deploy-remix-live: deploy-remix-live:
docker: docker:
# specify the version you desire here - image: cimg/node:14.17.6-browsers
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
resource_class: resource_class:
xlarge xlarge
# - image: circleci/mongo:3.4.4
environment: environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org" - COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI" - COMMIT_AUTHOR: "Circle CI"
@ -494,9 +177,6 @@ jobs:
steps: steps:
- checkout - checkout
- node/install:
install-yarn: true
node-version: "v14.17.6"
- run: yarn - run: yarn
- run: yarn run downloadsolc_assets - run: yarn run downloadsolc_assets
- run: yarn run build:production - run: yarn run build:production
@ -509,15 +189,10 @@ jobs:
deploy-remix-alpha: deploy-remix-alpha:
docker: docker:
# specify the version you desire here - image: cimg/node:14.17.6-browsers
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
resource_class: resource_class:
xlarge xlarge
# documented at https://circleci.com/docs/2.0/circleci-images/
# - image: circleci/mongo:3.4.4
environment: environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org" - COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI" - COMMIT_AUTHOR: "Circle CI"
@ -526,9 +201,6 @@ jobs:
steps: steps:
- checkout - checkout
- node/install:
install-yarn: true
node-version: "v14.17.6"
- run: yarn - run: yarn
- run: yarn run downloadsolc_assets - run: yarn run downloadsolc_assets
- run: yarn run build:production - run: yarn run build:production
@ -541,15 +213,10 @@ jobs:
deploy-remix-beta: deploy-remix-beta:
docker: docker:
# specify the version you desire here - image: cimg/node:14.17.6-browsers
- image: cimg/base:current
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
resource_class: resource_class:
xlarge xlarge
# documented at https://circleci.com/docs/2.0/circleci-images/
# - image: circleci/mongo:3.4.4
environment: environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org" - COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI" - COMMIT_AUTHOR: "Circle CI"
@ -558,9 +225,6 @@ jobs:
steps: steps:
- checkout - checkout
- node/install:
install-yarn: true
node-version: "v14.17.6"
- run: yarn - run: yarn
- run: yarn run build:libs - run: yarn run build:libs
- run: yarn run downloadsolc_assets - run: yarn run downloadsolc_assets
@ -577,12 +241,15 @@ workflows:
when: << pipeline.parameters.run_flaky_tests >> when: << pipeline.parameters.run_flaky_tests >>
jobs: jobs:
- build - build
- flaky-chrome: - remix-ide-browser:
requires:
- build
- flaky-firefox:
requires: requires:
- build - build
matrix:
parameters:
browser: ["chrome", "firefox"]
script: ["flaky.sh"]
job: ["nogroup"]
jobsize: ["1"]
build_all: build_all:
unless: << pipeline.parameters.run_flaky_tests >> unless: << pipeline.parameters.run_flaky_tests >>
jobs: jobs:
@ -593,30 +260,33 @@ workflows:
- remix-libs: - remix-libs:
requires: requires:
- build - build
- remix-ide-plugin-api: - remix-test-plugins:
requires:
- build
- remix-ide-vyper-plugin:
requires:
- build
- remix-ide-etherscan-plugin:
requires: requires:
- build - build
- remix-ide-chrome: matrix:
parameters:
script: ["browser_tests_plugin_api.sh", "browser_tests_etherscan_plugin.sh", "browser_tests_vyper_plugin.sh"]
- remix-ide-browser:
requires: requires:
- build - build
- remix-ide-firefox: matrix:
parameters:
browser: ["chrome", "firefox"]
script: ["browser_test.sh"]
job: ["0","1","2","3","4","5","6","7","8","9"]
jobsize: ["10"]
- tests-passed:
requires: requires:
- build - lint
- remix-libs
- remix-ide-browser
- remix-test-plugins
- deploy-remix-live: - deploy-remix-live:
requires: requires:
- lint - lint
- remix-libs - remix-libs
- remix-ide-chrome - remix-ide-browser
- remix-ide-firefox - remix-test-plugins
- remix-ide-plugin-api
- remix-ide-vyper-plugin
- remix-ide-etherscan-plugin
filters: filters:
branches: branches:
only: remix_live only: remix_live
@ -624,11 +294,8 @@ workflows:
requires: requires:
- lint - lint
- remix-libs - remix-libs
- remix-ide-chrome - remix-ide-browser
- remix-ide-firefox - remix-test-plugins
- remix-ide-plugin-api
- remix-ide-vyper-plugin
- remix-ide-etherscan-plugin
filters: filters:
branches: branches:
only: master only: master
@ -636,11 +303,8 @@ workflows:
requires: requires:
- lint - lint
- remix-libs - remix-libs
- remix-ide-chrome - remix-ide-browser
- remix-ide-firefox - remix-test-plugins
- remix-ide-plugin-api
- remix-ide-vyper-plugin
- remix-ide-etherscan-plugin
filters: filters:
branches: branches:
only: remix_beta only: remix_beta

@ -14,7 +14,11 @@ class addAtAddressInstance extends EventEmitter {
} }
function addInstance (browser: NightwatchBrowser, address: string, isValidFormat: boolean, isValidChecksum: boolean, isAbi: boolean, callback: VoidFunction) { function addInstance (browser: NightwatchBrowser, address: string, isValidFormat: boolean, isValidChecksum: boolean, isAbi: boolean, callback: VoidFunction) {
browser.clickLaunchIcon('udapp').clearValue('.ataddressinput').setValue('.ataddressinput', address, function () { browser
.clickLaunchIcon('udapp')
.waitForElementVisible('.ataddressinput')
.click('.ataddressinput')
.setValue('.ataddressinput', address, function () {
if (!isValidFormat || !isValidChecksum) browser.assert.elementPresent('button[id^="runAndDeployAtAdressButton"]:disabled') if (!isValidFormat || !isValidChecksum) browser.assert.elementPresent('button[id^="runAndDeployAtAdressButton"]:disabled')
else if (isAbi) { else if (isAbi) {
browser.click('button[id^="runAndDeployAtAdressButton"]') browser.click('button[id^="runAndDeployAtAdressButton"]')

@ -13,26 +13,31 @@ class AddFile extends EventEmitter {
} }
} }
function addFile (browser: NightwatchBrowser, name: string, content: NightwatchContractContent, done: VoidFunction) { function addFile(browser: NightwatchBrowser, name: string, content: NightwatchContractContent, done: VoidFunction) {
browser browser
.saveScreenshot('./reports/screenshots/addFile.png')
.isVisible({ .isVisible({
selector: "//*[@data-id='sidePanelSwapitTitle' and contains(.,'File explorer')]", selector: "//*[@data-id='sidePanelSwapitTitle' and contains(.,'File explorer')]",
locateStrategy: 'xpath', locateStrategy: 'xpath',
suppressNotFoundErrors: true, suppressNotFoundErrors: true,
timeout: 1000 timeout: 1000
}, (okVisible) => { }, (okVisible) => {
if (!okVisible.value) { if (!okVisible.value) {
browser.clickLaunchIcon('filePanel') browser.clickLaunchIcon('filePanel')
.saveScreenshot('./reports/screenshots/addFile2.png')
} }
}) })
.scrollInto('li[data-id="treeViewLitreeViewItemREADME.txt"]') .scrollInto('li[data-id="treeViewLitreeViewItemREADME.txt"]')
.saveScreenshot('./reports/screenshots/addFile3.png')
.waitForElementVisible('li[data-id="treeViewLitreeViewItemREADME.txt"]') .waitForElementVisible('li[data-id="treeViewLitreeViewItemREADME.txt"]')
.click('li[data-id="treeViewLitreeViewItemREADME.txt"]').pause(1000) // focus on root directory .click('li[data-id="treeViewLitreeViewItemREADME.txt"]').pause(1000) // focus on root directory
.elements('css selector', `li[data-id="treeViewLitreeViewItem${name}"]`, (res) => { .isVisible({
if (res.value && (res.value as any).length > 0) { selector: `//*[@data-id="treeViewLitreeViewItem${name}"]`,
locateStrategy: 'xpath',
abortOnFailure: false,
suppressNotFoundErrors: true,
timeout: 2000
}, (okVisible) => {
// @ts-ignore
// status === -1 means the element is not visible, 0 means it is visible.
if (okVisible.status === 0) {
browser.openFile(name) browser.openFile(name)
.perform(function () { .perform(function () {
done() done()
@ -42,10 +47,14 @@ function addFile (browser: NightwatchBrowser, name: string, content: NightwatchC
.waitForElementContainsText('*[data-id$="/blank"]', '', 60000) .waitForElementContainsText('*[data-id$="/blank"]', '', 60000)
.sendKeys('*[data-id$="/blank"] .remixui_items', name) .sendKeys('*[data-id$="/blank"] .remixui_items', name)
.sendKeys('*[data-id$="/blank"] .remixui_items', browser.Keys.ENTER) .sendKeys('*[data-id$="/blank"] .remixui_items', browser.Keys.ENTER)
.pause(2000) // isvisible is protocol action called isDisplayed https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/WebElement.html#isDisplayed--
.waitForElementVisible(`li[data-id="treeViewLitreeViewItem${name}"]`, 60000) .isVisible({
selector: `li[data-id="treeViewLitreeViewItem${name}"]`,
abortOnFailure: false,
suppressNotFoundErrors: true,
timeout: 60000
})
.setEditorValue(content.content) .setEditorValue(content.content)
.pause(1000)
.perform(function () { .perform(function () {
done() done()
}) })

@ -4,7 +4,7 @@ import EventEmitter from 'events'
const deepequal = require('deep-equal') const deepequal = require('deep-equal')
class CheckVariableDebug extends EventEmitter { class CheckVariableDebug extends EventEmitter {
command (this: NightwatchBrowser, id: string, debugValue: NightwatchCheckVariableDebugValue): NightwatchBrowser { command(this: NightwatchBrowser, id: string, debugValue: NightwatchCheckVariableDebugValue): NightwatchBrowser {
this.api.perform((done) => { this.api.perform((done) => {
checkDebug(this.api, id, debugValue, () => { checkDebug(this.api, id, debugValue, () => {
done() done()
@ -15,27 +15,36 @@ class CheckVariableDebug extends EventEmitter {
} }
} }
function checkDebug (browser: NightwatchBrowser, id: string, debugValue: NightwatchCheckVariableDebugValue, done: VoidFunction) { function checkDebug(browser: NightwatchBrowser, id: string, debugValue: NightwatchCheckVariableDebugValue, done: VoidFunction) {
// id is soliditylocals or soliditystate // id is soliditylocals or soliditystate
browser.execute(function (id: string) { let resultOfElement = null
const elem = document.querySelector('#' + id + ' .dropdownrawcontent') as HTMLElement let isEqual = false
// waitUntil will run with intervals of 1000ms for 10 seconds until the condition is met
return elem.innerText browser.waitUntil(() => {
}, [id], function (result) { browser.execute(function (id: string) {
let value const elem = document.querySelector('#' + id + ' .dropdownrawcontent') as HTMLElement
try { if (elem && elem.innerText) {
value = JSON.parse(<string>result.value) return elem.innerText
} catch (e) { }
browser.assert.fail('cant parse solidity state', e.message, '') }, [id], (result) => {
if (result.value) {
try {
resultOfElement = JSON.parse(<string>result.value)
isEqual = deepequal(debugValue, resultOfElement)
} catch (e) {
browser.assert.fail('cant parse solidity state', e.message, '')
}
}
})
if (isEqual) return true
return false
}, 10000, 1000)
.perform(() => {
if (!isEqual) {
browser.assert.fail(JSON.stringify(resultOfElement), 'info about error\n ' + JSON.stringify(debugValue) + '\n ' + JSON.stringify(resultOfElement), '')
}
done() done()
return })
}
const equal = deepequal(debugValue, value)
if (!equal) {
browser.assert.fail(JSON.stringify(value), 'info about error\n ' + JSON.stringify(debugValue) + '\n ' + JSON.stringify(value), '')
}
done()
})
} }
module.exports = CheckVariableDebug module.exports = CheckVariableDebug

@ -3,7 +3,10 @@ import EventEmitter from 'events'
class ClickLaunchIcon extends EventEmitter { class ClickLaunchIcon extends EventEmitter {
command (this: NightwatchBrowser, icon: string): NightwatchBrowser { command (this: NightwatchBrowser, icon: string): NightwatchBrowser {
this.api.waitForElementVisible('#icon-panel div[plugin="' + icon + '"]').click('#icon-panel div[plugin="' + icon + '"]').perform((done) => { this.api
.waitForElementVisible('#icon-panel div[plugin="' + icon + '"]')
.click('#icon-panel div[plugin="' + icon + '"]')
.perform((done) => {
done() done()
this.emit('complete') this.emit('complete')
}) })

@ -17,7 +17,10 @@ function goToVMtraceStep (browser: NightwatchBrowser, step: number, incr: number
.execute((step) => { .execute((step) => {
(document.querySelector('*[data-id="slider"]') as any).internal_onmouseup({ target: { value: step }}) (document.querySelector('*[data-id="slider"]') as any).internal_onmouseup({ target: { value: step }})
}, [step]) }, [step])
.pause(10000) .waitForElementVisible({
locateStrategy: 'xpath',
selector: `//*[@data-id="treeViewLivm trace step" and contains(.,"${step}")]`,
})
.perform(() => { .perform(() => {
done() done()
}) })

@ -0,0 +1,16 @@
import { NightwatchBrowser } from 'nightwatch'
import EventEmitter from 'events'
class RefreshPage extends EventEmitter {
command(this: NightwatchBrowser) {
browser.refresh()
.verifyLoad()
.perform((done) => {
done()
this.emit('complete')
})
}
}
module.exports = RefreshPage

@ -2,10 +2,22 @@ import { NightwatchBrowser } from 'nightwatch'
import EventEmitter from 'events' import EventEmitter from 'events'
class SetSolidityCompilerVersion extends EventEmitter { class SetSolidityCompilerVersion extends EventEmitter {
command (this: NightwatchBrowser, version: string): NightwatchBrowser { command(this: NightwatchBrowser, version: string): NightwatchBrowser {
this.api this.api
.waitForElementVisible({
selector: "//*[@id='versionSelector']",
locateStrategy: 'xpath'
})
.waitForElementPresent({
selector: `//option[@value='${version}']`,
locateStrategy: 'xpath'
})
.click(`#compileTabView #versionSelector [value="${version}"]`) .click(`#compileTabView #versionSelector [value="${version}"]`)
.pause(5000) .waitForElementPresent({
selector: `//span[@data-version='${version}']`,
locateStrategy: 'xpath',
timeout: 60000
})
.perform(() => { .perform(() => {
this.emit('complete') this.emit('complete')
}) })

@ -3,12 +3,12 @@ import EventEmitter from 'events'
class switchWorkspace extends EventEmitter { class switchWorkspace extends EventEmitter {
command (this: NightwatchBrowser, workspaceName: string): NightwatchBrowser { command (this: NightwatchBrowser, workspaceName: string): NightwatchBrowser {
this.api.waitForElementVisible('[data-id="workspacesSelect"]') this.api
.waitForElementVisible('[data-id="workspacesSelect"]')
.click('[data-id="workspacesSelect"]') .click('[data-id="workspacesSelect"]')
.waitForElementVisible(`[data-id="dropdown-item-${workspaceName}"]`) .waitForElementVisible(`[data-id="dropdown-item-${workspaceName}"]`)
.pause(2000)
.click(`[data-id="dropdown-item-${workspaceName}"]`) .click(`[data-id="dropdown-item-${workspaceName}"]`)
.pause(3000) .pause(7000)
.perform((done) => { .perform((done) => {
done() done()
this.emit('complete') this.emit('complete')

@ -0,0 +1,38 @@
import { NightwatchBrowser } from 'nightwatch'
import EventEmitter from 'events'
class VerifyLoad extends EventEmitter {
command(this: NightwatchBrowser) {
browser.waitForElementPresent({
selector: "//span[@data-id='typesloaded']",
locateStrategy: 'xpath',
timeout: 60000
})
.waitForElementPresent({
selector: "//span[@data-id='editorloaded']",
locateStrategy: 'xpath',
timeout: 60000
})
.waitForElementPresent({
selector: "//span[@data-id='workspaceloaded']",
locateStrategy: 'xpath',
timeout: 60000
})
.waitForElementPresent({
selector: "//span[@data-id='apploaded']",
locateStrategy: 'xpath',
timeout: 60000
})
.waitForElementPresent({
selector: "//span[@data-id='compilerloaded']",
locateStrategy: 'xpath',
timeout: 120000
})
.perform((done) => {
done()
this.emit('complete')
})
}
}
module.exports = VerifyLoad

@ -10,38 +10,42 @@ type LoadPlugin = {
export default function (browser: NightwatchBrowser, callback: VoidFunction, url?: string, preloadPlugins = true, loadPlugin?: LoadPlugin): void { export default function (browser: NightwatchBrowser, callback: VoidFunction, url?: string, preloadPlugins = true, loadPlugin?: LoadPlugin): void {
browser browser
.url(url || 'http://127.0.0.1:8080') .url(url || 'http://127.0.0.1:8080')
.pause(6000) //.switchBrowserTab(0)
.switchBrowserTab(0)
.waitForElementVisible('[id="remixTourSkipbtn"]') .waitForElementVisible('[id="remixTourSkipbtn"]')
.click('[id="remixTourSkipbtn"]') .click('[id="remixTourSkipbtn"]')
.perform((done) => { .perform((done) => {
if (!loadPlugin) return done() if (!loadPlugin) return done()
browser.execute(function (loadPlugin) { // override a plugin url for testing purpose browser
localStorage.setItem('test-plugin-name', loadPlugin.name) .pause(5000)
localStorage.setItem('test-plugin-url', loadPlugin.url) .execute(function (loadPlugin) { // override a plugin url for testing purpose
}, [loadPlugin]) localStorage.setItem('test-plugin-name', loadPlugin.name)
.refresh() localStorage.setItem('test-plugin-url', loadPlugin.url)
.pause(6000) }, [loadPlugin])
.perform(done()) .refreshPage()
.perform(done())
}) })
//.maximizeWindow() .verifyLoad()
.perform(() => { .perform(() => {
if (preloadPlugins) { if (preloadPlugins) {
initModules(browser, () => { initModules(browser, () => {
browser.pause(2000).clickLaunchIcon('solidity') browser
.clickLaunchIcon('solidity')
.waitForElementVisible('[for="autoCompile"]') .waitForElementVisible('[for="autoCompile"]')
.click('[for="autoCompile"]') .click('[for="autoCompile"]')
.verify.elementPresent('[data-id="compilerContainerAutoCompile"]:checked') .verify.elementPresent('[data-id="compilerContainerAutoCompile"]:checked')
.perform(() => { callback() })
}) })
} else {
callback()
} }
}) })
.perform(() => {
callback()
})
} }
function initModules (browser: NightwatchBrowser, callback: VoidFunction) { function initModules(browser: NightwatchBrowser, callback: VoidFunction) {
browser.pause(5000) browser
.click('[data-id="verticalIconsKindpluginManager"]') .click('[data-id="verticalIconsKindpluginManager"]')
.scrollAndClick('[data-id="pluginManagerComponentActivateButtonsolidityStaticAnalysis"]') .scrollAndClick('[data-id="pluginManagerComponentActivateButtonsolidityStaticAnalysis"]')
.scrollAndClick('[data-id="pluginManagerComponentActivateButtondebugger"]') .scrollAndClick('[data-id="pluginManagerComponentActivateButtondebugger"]')

@ -31,7 +31,7 @@ do
done done
yarn 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" | sort ) )
# declare -p TESTFILES # declare -p TESTFILES
TESTFILES+=("list") TESTFILES+=("list")

@ -131,12 +131,98 @@ module.exports = {
.click('*[data-id="scConfigExpander"]') .click('*[data-id="scConfigExpander"]')
.waitForElementVisible('*[data-id="scFileConfiguration"]', 10000) .waitForElementVisible('*[data-id="scFileConfiguration"]', 10000)
.click('*[data-id="scFileConfiguration"]') .click('*[data-id="scFileConfiguration"]')
.waitForElementVisible('*[data-id="scConfigChangeFilePath"]', 10000) // the input field behaves badly, it would often not receive the value, so retrying it a few times for now is the best thing to do
.click('*[data-id="scConfigChangeFilePath"]') .waitForElementVisible({
selector: '*[data-id="scConfigChangeFilePath"]',
abortOnFailure: false
}, 10000)
.click({
selector: '*[data-id="scConfigChangeFilePath"]',
suppressNotFoundErrors: true,
timeout: 1000
})
.click({
selector: '*[data-id="scConfigChangeFilePath"]',
suppressNotFoundErrors: true,
timeout: 1000
})
.click({
selector: '*[data-id="scConfigChangeFilePath"]',
suppressNotFoundErrors: true,
timeout: 1000
})
.waitForElementVisible('*[data-id="scConfigFilePathInput"]', 10000) .waitForElementVisible('*[data-id="scConfigFilePathInput"]', 10000)
.clearValue('*[data-id="scConfigFilePathInput"]') .sendKeys('*[data-id="scConfigFilePathInput"]', 'cf.json')
.setValue('*[data-id="scConfigFilePathInput"]', 'cf.json') .sendKeys('*[data-id="scConfigFilePathInput"]', browser.Keys.ENTER)
.sendKeys('*[data-id$="scConfigFilePathInput"]', browser.Keys.ENTER)
.isVisible({
selector:"//*[@class='py-2 remixui_compilerConfigPath' and contains(.,'cf.json')]",
suppressNotFoundErrors: true,
locateStrategy: 'xpath'
}, (okVisible) => {
// if it's not there yet, try again
if (!okVisible.value) {
browser.waitForElementVisible({
selector: '*[data-id="scConfigChangeFilePath"]',
abortOnFailure: false
}, 10000)
.click({
selector: '*[data-id="scConfigChangeFilePath"]',
suppressNotFoundErrors: true,
timeout: 1000
})
.click({
selector: '*[data-id="scConfigChangeFilePath"]',
suppressNotFoundErrors: true,
timeout: 1000
})
.click({
selector: '*[data-id="scConfigChangeFilePath"]',
suppressNotFoundErrors: true,
timeout: 1000
})
.waitForElementVisible('*[data-id="scConfigFilePathInput"]', 10000)
.sendKeys('*[data-id="scConfigFilePathInput"]', 'cf.json')
.sendKeys('*[data-id="scConfigFilePathInput"]', browser.Keys.ENTER)
}
})
.isVisible({
selector:"//*[@class='py-2 remixui_compilerConfigPath' and contains(.,'cf.json')]",
suppressNotFoundErrors: true,
locateStrategy: 'xpath'
}, (okVisible) => {
if (!okVisible.value) {
// if it's still not there, try again
browser.waitForElementVisible({
selector: '*[data-id="scConfigChangeFilePath"]',
abortOnFailure: false
}, 10000)
.click({
selector: '*[data-id="scConfigChangeFilePath"]',
suppressNotFoundErrors: true,
timeout: 1000
})
.click({
selector: '*[data-id="scConfigChangeFilePath"]',
suppressNotFoundErrors: true,
timeout: 1000
})
.click({
selector: '*[data-id="scConfigChangeFilePath"]',
suppressNotFoundErrors: true,
timeout: 1000
})
.waitForElementVisible('*[data-id="scConfigFilePathInput"]', 10000)
.sendKeys('*[data-id="scConfigFilePathInput"]', 'cf.json')
.sendKeys('*[data-id="scConfigFilePathInput"]', browser.Keys.ENTER)
}
})
.pause(5000)
.openFile('Untitled.sol') .openFile('Untitled.sol')
.verifyContracts(['Ballot'], { wait: 2000, runs: '300' }) .verifyContracts(['Ballot'], { wait: 2000, runs: '300' })
}, },

@ -16,16 +16,21 @@ module.exports = {
'@sources': function () { '@sources': function () {
return sources return sources
}, },
'Set Ballot 0.4.11': function (browser: NightwatchBrowser) { 'Add Ballot': function (browser: NightwatchBrowser) {
browser
.addFile('Untitled.sol', sources[0]['Untitled.sol'])
},
'Set Ballot 0.4.14': function (browser: NightwatchBrowser) {
browser browser
.waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000) .waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000)
.clickLaunchIcon('solidity') .clickLaunchIcon('solidity')
.setSolidityCompilerVersion('soljson-v0.4.11+commit.68ef5810.js') .setSolidityCompilerVersion('soljson-v0.4.14+commit.c2215d46.js')
.waitForElementVisible('[for="autoCompile"]') .waitForElementVisible('[for="autoCompile"]')
.click('[for="autoCompile"]') .click('[for="autoCompile"]')
.verify.elementPresent('[data-id="compilerContainerAutoCompile"]:checked') .verify.elementPresent('[data-id="compilerContainerAutoCompile"]:checked')
}, },
'Compile Ballot with compiler version 0.4.11 #group1 #group2': function (browser: NightwatchBrowser) {
'Compile Ballot with compiler version 0.4.14': function (browser: NightwatchBrowser) {
browser browser
.testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['Ballot']) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['Ballot'])
}, },

@ -14,8 +14,12 @@ module.exports = {
'Should launch debugger #group1': function (browser: NightwatchBrowser) { 'Should launch debugger #group1': function (browser: NightwatchBrowser) {
browser.addFile('blah.sol', sources[0]['blah.sol']) browser.addFile('blah.sol', sources[0]['blah.sol'])
.pause(4000)
// on autocompile sometimes the compiler returns invalid source, so we need to recompile to make sure the source is valid
.clickLaunchIcon('solidity').click('*[data-id="compilerContainerCompileBtn"]')
.pause(4000)
.clickLaunchIcon('udapp') .clickLaunchIcon('udapp')
.waitForElementPresent('*[title="Deploy - transact (not payable)"]', 65000) .waitForElementPresent('*[title="Deploy - transact (not payable)"]', 60000)
.click('*[title="Deploy - transact (not payable)"]') .click('*[title="Deploy - transact (not payable)"]')
.debugTransaction(0) .debugTransaction(0)
.waitForElementContainsText('*[data-id="sidePanelSwapitTitle"]', 'DEBUGGER', 60000) .waitForElementContainsText('*[data-id="sidePanelSwapitTitle"]', 'DEBUGGER', 60000)
@ -62,10 +66,10 @@ module.exports = {
browser.waitForElementVisible('#editorView') browser.waitForElementVisible('#editorView')
.execute(() => { .execute(() => {
(window as any).addRemixBreakpoint(11) (window as any).addRemixBreakpoint(11)
}, [], () => {}) }, [], () => { })
.execute(() => { .execute(() => {
(window as any).addRemixBreakpoint(21) (window as any).addRemixBreakpoint(21)
}, [], () => {}) }, [], () => { })
.waitForElementVisible('*[data-id="buttonNavigatorJumpPreviousBreakpoint"]') .waitForElementVisible('*[data-id="buttonNavigatorJumpPreviousBreakpoint"]')
.click('*[data-id="buttonNavigatorJumpPreviousBreakpoint"]') .click('*[data-id="buttonNavigatorJumpPreviousBreakpoint"]')
.pause(2000) .pause(2000)
@ -88,15 +92,22 @@ module.exports = {
.selectContract('ERC20') .selectContract('ERC20')
.createContract('"tokenName", "symbol"') .createContract('"tokenName", "symbol"')
.debugTransaction(0) .debugTransaction(0)
.pause(2000)
.waitForElementVisible('#stepdetail') .waitForElementVisible('#stepdetail')
.waitForElementVisible({
locateStrategy: 'xpath',
selector: '//*[@data-id="treeViewLivm trace step" and contains(.,"545")]',
})
.goToVMTraceStep(10) .goToVMTraceStep(10)
.waitForElementVisible({
locateStrategy: 'xpath',
selector: '//*[@data-id="treeViewLivm trace step" and contains(.,"10")]',
})
.getEditorValue((content) => { .getEditorValue((content) => {
browser.assert.ok(content.indexOf(`constructor (string memory name_, string memory symbol_) { browser.assert.ok(content.indexOf(`constructor (string memory name_, string memory symbol_) {
_name = name_; _name = name_;
_symbol = symbol_; _symbol = symbol_;
}`) !== -1, }`) !== -1,
'current displayed content is not from the ERC20 source code') 'current displayed content is not from the ERC20 source code')
}) })
}, },
@ -120,24 +131,25 @@ module.exports = {
.clickInstance(0) .clickInstance(0)
.clickFunction('test1 - transact (not payable)', { types: 'bytes userData', values: '0x000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000015b38da6a701c568545dcfcb03fcb875f56beddc4' }) .clickFunction('test1 - transact (not payable)', { types: 'bytes userData', values: '0x000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000015b38da6a701c568545dcfcb03fcb875f56beddc4' })
.debugTransaction(0) .debugTransaction(0)
.pause(2000)
.waitForElementVisible('#stepdetail') .waitForElementVisible('#stepdetail')
.waitForElementVisible({
locateStrategy: 'xpath',
selector: '//*[@data-id="treeViewLivm trace step" and contains(.,"133")]',
})
.goToVMTraceStep(261) .goToVMTraceStep(261)
.pause(1000)
/*
for the test below:
source highlight should remain line `bytes32 idAsk = abi.decode(userData[:33], (bytes32));`
At this vmtrace index, the sourcemap has file = -1 because the execution is in the generated sources (ABIEncoderV2)
the atIndex of SourceLocationTracker was buggy and return an incorrect value, this is fixed
But the debugger uses now validSourcelocation, which means file is not -1.
In that case the source highlight at 261 should be the same as for step 262
*/
.waitForElementPresent('.highlightLine8') .waitForElementPresent('.highlightLine8')
/*
for the test below:
source highlight should remain line `bytes32 idAsk = abi.decode(userData[:33], (bytes32));`
At this vmtrace index, the sourcemap has file = -1 because the execution is in the generated sources (ABIEncoderV2)
the atIndex of SourceLocationTracker was buggy and return an incorrect value, this is fixed
But the debugger uses now validSourcelocation, which means file is not -1.
In that case the source highlight at 261 should be the same as for step 262
*/
.goToVMTraceStep(266) .goToVMTraceStep(266)
.pause(1000)
.checkVariableDebug('soliditylocals', localVariable_step266_ABIEncoder) // locals should not be initiated at this point, only idAsk should .checkVariableDebug('soliditylocals', localVariable_step266_ABIEncoder) // locals should not be initiated at this point, only idAsk should
.goToVMTraceStep(717) .goToVMTraceStep(717)
.pause(5000)
.checkVariableDebug('soliditylocals', localVariable_step717_ABIEncoder) // all locals should be initiaed .checkVariableDebug('soliditylocals', localVariable_step717_ABIEncoder) // all locals should be initiaed
.clearTransactions() .clearTransactions()
}, },
@ -228,7 +240,7 @@ module.exports = {
.waitForElementVisible('*[data-id="solidityLocals"]', 60000) .waitForElementVisible('*[data-id="solidityLocals"]', 60000)
.pause(10000) .pause(10000)
.checkVariableDebug('soliditylocals', { num: { value: '2', type: 'uint256' } }) .checkVariableDebug('soliditylocals', { num: { value: '2', type: 'uint256' } })
.checkVariableDebug('soliditystate', { number: { value: '0', type: 'uint256', constant: false, immutable: false } }) .checkVariableDebug('soliditystate', { number: { value: '0', type: 'uint256', constant: false, immutable: false } })
}, },
'Should debug reverted transactions #group5': function (browser: NightwatchBrowser) { 'Should debug reverted transactions #group5': function (browser: NightwatchBrowser) {

@ -28,6 +28,31 @@ module.exports = {
.waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts"]') .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts/MyToken.sol"]') .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts/MyToken.sol"]')
.openFile('contracts/MyToken.sol') .openFile('contracts/MyToken.sol')
// because the compilatiom imports are slow and sometimes stop loading (not sure why, it's bug) we need to recompile and check to see if the files are really in de FS
.clickLaunchIcon('solidity')
.pause(2000)
.click('[data-id="compilerContainerCompileBtn"]')
.clickLaunchIcon('filePanel')
.isVisible({
selector: '*[data-id="treeViewLitreeViewItem.deps/npm/@openzeppelin/contracts/utils/introspection/IERC165.sol"]',
timeout: 120000,
suppressNotFoundErrors: true
})
.clickLaunchIcon('solidity')
.click('[data-id="compilerContainerCompileBtn"]')
.clickLaunchIcon('filePanel')
.isVisible({
selector: '*[data-id="treeViewLitreeViewItem.deps/npm/@openzeppelin/contracts/utils/introspection/IERC165.sol"]',
timeout: 120000,
suppressNotFoundErrors: true
})
.clickLaunchIcon('solidity')
.click('[data-id="compilerContainerCompileBtn"]')
.clickLaunchIcon('filePanel')
.waitForElementVisible({
selector: '*[data-id="treeViewLitreeViewItem.deps/npm/@openzeppelin/contracts/utils/introspection/IERC165.sol"]',
timeout: 120000,
})
.verifyContracts(['MyToken']) .verifyContracts(['MyToken'])
// deploy contract // deploy contract
.clickLaunchIcon('udapp') .clickLaunchIcon('udapp')

@ -77,7 +77,7 @@ module.exports = {
'Should publish all explorer files to github gist': '' + function (browser: NightwatchBrowser) { 'Should publish all explorer files to github gist': '' + function (browser: NightwatchBrowser) {
const runtimeBrowser = browser.options.desiredCapabilities.browserName const runtimeBrowser = browser.options.desiredCapabilities.browserName
browser.refresh() browser.refreshPage()
.pause(10000) .pause(10000)
.waitForElementVisible('*[data-id="fileExplorerNewFilepublishToGist"]') .waitForElementVisible('*[data-id="fileExplorerNewFilepublishToGist"]')
.click('*[data-id="fileExplorerNewFilepublishToGist"]') .click('*[data-id="fileExplorerNewFilepublishToGist"]')

@ -23,7 +23,7 @@ module.exports = {
console.log('token', process.env.gist_token) console.log('token', process.env.gist_token)
const gistid = '17ac9315bc065a3d95cf8dc1b28d71f8' const gistid = '17ac9315bc065a3d95cf8dc1b28d71f8'
browser browser
.refresh() .refreshPage()
.pause(10000) .pause(10000)
.waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000) .waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000)
.click('li[data-id="treeViewLitreeViewItemREADME.txt"]') // focus on root directory .click('li[data-id="treeViewLitreeViewItemREADME.txt"]') // focus on root directory

@ -22,7 +22,7 @@ module.exports = {
.waitForElementVisible('*[data-id="skipbackup-btn"]', 5000) .waitForElementVisible('*[data-id="skipbackup-btn"]', 5000)
.click('*[data-id="skipbackup-btn"]') .click('*[data-id="skipbackup-btn"]')
.waitForElementVisible('[id="remixTourSkipbtn"]') .waitForElementVisible('[id="remixTourSkipbtn"]')
.click('[id="remixTourSkipbtn"]').refresh() .click('[id="remixTourSkipbtn"]').refreshPage()
}, },
'should have indexedDB storage in terminal #group1 #group7': function (browser: NightwatchBrowser) { 'should have indexedDB storage in terminal #group1 #group7': function (browser: NightwatchBrowser) {
browser.assert.containsText('*[data-id="terminalJournal"]', 'indexedDB') browser.assert.containsText('*[data-id="terminalJournal"]', 'indexedDB')

@ -112,7 +112,7 @@ module.exports = {
.waitForElementVisible('*[data-id="remixIdeSidePanel"]',3000) .waitForElementVisible('*[data-id="remixIdeSidePanel"]',3000)
.waitForElementVisible('*[data-id="pluginManagerComponentPluginManager"]') .waitForElementVisible('*[data-id="pluginManagerComponentPluginManager"]')
.getInstalledPlugins((plugins) => { .getInstalledPlugins((plugins) => {
browser.refresh() browser.refreshPage()
.waitForElementVisible('*[data-id="remixIdeSidePanel"]') .waitForElementVisible('*[data-id="remixIdeSidePanel"]')
.pause(3000) .pause(3000)
.perform((done) => { .perform((done) => {

@ -5,6 +5,7 @@ import init from '../helpers/init'
let firstProxyAddress: string let firstProxyAddress: string
let lastProxyAddress: string let lastProxyAddress: string
module.exports = { module.exports = {
'@disabled': true,
before: function (browser: NightwatchBrowser, done: VoidFunction) { before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done) init(browser, done)
}, },
@ -13,12 +14,36 @@ module.exports = {
return sources return sources
}, },
'Should show deploy proxy option for UUPS upgradeable contract': function (browser: NightwatchBrowser) {
'Should show deploy proxy option for UUPS upgradeable contract #group1': function (browser: NightwatchBrowser) {
browser browser
.addFile('myTokenV1.sol', sources[0]['myTokenV1.sol']) .addFile('myTokenV1.sol', sources[0]['myTokenV1.sol'])
.clickLaunchIcon('solidity') .clickLaunchIcon('solidity')
.pause(2000) .pause(2000)
// because the compilatiom imports are slow and sometimes stop loading (not sure why, it's bug) we need to recompile and check to see if the files are really in de FS
.click('[data-id="compilerContainerCompileBtn"]')
.clickLaunchIcon('filePanel')
.isVisible({
selector: '*[data-id="treeViewDivtreeViewItem.deps/npm/@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol"]',
timeout: 120000,
suppressNotFoundErrors: true
})
.clickLaunchIcon('solidity')
.click('[data-id="compilerContainerCompileBtn"]')
.clickLaunchIcon('filePanel')
.isVisible({
selector: '*[data-id="treeViewDivtreeViewItem.deps/npm/@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol"]',
timeout: 120000,
suppressNotFoundErrors: true
})
.clickLaunchIcon('solidity')
.click('[data-id="compilerContainerCompileBtn"]') .click('[data-id="compilerContainerCompileBtn"]')
.clickLaunchIcon('filePanel')
.waitForElementVisible({
selector: '*[data-id="treeViewDivtreeViewItem.deps/npm/@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol"]',
timeout: 120000,
})
.clickLaunchIcon('solidity')
.waitForElementPresent('select[id="compiledContracts"] option[value=MyToken]', 60000) .waitForElementPresent('select[id="compiledContracts"] option[value=MyToken]', 60000)
.clickLaunchIcon('udapp') .clickLaunchIcon('udapp')
.click('select.udapp_contractNames') .click('select.udapp_contractNames')
@ -27,7 +52,7 @@ module.exports = {
.waitForElementPresent('[data-id="contractGUIUpgradeImplementationLabel"]') .waitForElementPresent('[data-id="contractGUIUpgradeImplementationLabel"]')
}, },
'Should show upgrade proxy option for child contract inheriting UUPS parent contract': function (browser: NightwatchBrowser) { 'Should show upgrade proxy option for child contract inheriting UUPS parent contract #group1': function (browser: NightwatchBrowser) {
browser browser
.addFile('myTokenV2.sol', sources[1]['myTokenV2.sol']) .addFile('myTokenV2.sol', sources[1]['myTokenV2.sol'])
.clickLaunchIcon('solidity') .clickLaunchIcon('solidity')
@ -41,7 +66,7 @@ module.exports = {
.waitForElementPresent('[data-id="contractGUIUpgradeImplementationLabel"]') .waitForElementPresent('[data-id="contractGUIUpgradeImplementationLabel"]')
}, },
'Should deploy proxy without initialize parameters': function (browser: NightwatchBrowser) { 'Should deploy proxy without initialize parameters #group1': function (browser: NightwatchBrowser) {
browser browser
.openFile('myTokenV1.sol') .openFile('myTokenV1.sol')
.clickLaunchIcon('solidity') .clickLaunchIcon('solidity')
@ -64,7 +89,7 @@ module.exports = {
.waitForElementPresent('[data-id="universalDappUiTitleExpander1"]') .waitForElementPresent('[data-id="universalDappUiTitleExpander1"]')
}, },
'Should interact with deployed contract via ERC1967 (proxy)': function (browser: NightwatchBrowser) { 'Should interact with deployed contract via ERC1967 (proxy) #group1': function (browser: NightwatchBrowser) {
browser browser
.getAddressAtPosition(1, (address) => { .getAddressAtPosition(1, (address) => {
firstProxyAddress = address firstProxyAddress = address
@ -82,7 +107,7 @@ module.exports = {
}) })
}, },
'Should deploy proxy with initialize parameters': function (browser: NightwatchBrowser) { 'Should deploy proxy with initialize parameters #group1': function (browser: NightwatchBrowser) {
browser browser
.waitForElementPresent('[data-id="deployAndRunClearInstances"]') .waitForElementPresent('[data-id="deployAndRunClearInstances"]')
.click('[data-id="deployAndRunClearInstances"]') .click('[data-id="deployAndRunClearInstances"]')
@ -111,7 +136,7 @@ module.exports = {
.waitForElementPresent('[data-id="universalDappUiTitleExpander1"]') .waitForElementPresent('[data-id="universalDappUiTitleExpander1"]')
}, },
'Should interact with initialized contract to verify parameters': function (browser: NightwatchBrowser) { 'Should interact with initialized contract to verify parameters #group1': function (browser: NightwatchBrowser) {
browser browser
.getAddressAtPosition(1, (address) => { .getAddressAtPosition(1, (address) => {
lastProxyAddress = address lastProxyAddress = address
@ -129,7 +154,7 @@ module.exports = {
}) })
}, },
'Should upgrade contract using last deployed proxy address (MyTokenV1 to MyTokenV2)': function (browser: NightwatchBrowser) { 'Should upgrade contract using last deployed proxy address (MyTokenV1 to MyTokenV2) #group1': function (browser: NightwatchBrowser) {
browser browser
.waitForElementPresent('[data-id="deployAndRunClearInstances"]') .waitForElementPresent('[data-id="deployAndRunClearInstances"]')
.click('[data-id="deployAndRunClearInstances"]') .click('[data-id="deployAndRunClearInstances"]')
@ -153,12 +178,15 @@ module.exports = {
.click('[data-id="udappNotify-modal-footer-ok-react"]') .click('[data-id="udappNotify-modal-footer-ok-react"]')
.waitForElementContainsText('[data-id="confirmProxyDeploymentModalDialogModalTitle-react"]', 'Confirm Update Proxy (ERC1967)') .waitForElementContainsText('[data-id="confirmProxyDeploymentModalDialogModalTitle-react"]', 'Confirm Update Proxy (ERC1967)')
.waitForElementVisible('[data-id="confirmProxyDeployment-modal-footer-ok-react"]') .waitForElementVisible('[data-id="confirmProxyDeployment-modal-footer-ok-react"]')
.click('[data-id="confirmProxyDeployment-modal-footer-ok-react"]') .click(
{
selector: '[data-id="confirmProxyDeployment-modal-footer-ok-react"]',
})
.waitForElementPresent('[data-id="universalDappUiTitleExpander0"]') .waitForElementPresent('[data-id="universalDappUiTitleExpander0"]')
.waitForElementPresent('[data-id="universalDappUiTitleExpander1"]') .waitForElementPresent('[data-id="universalDappUiTitleExpander1"]')
}, },
'Should interact with upgraded function in contract MyTokenV2': function (browser: NightwatchBrowser) { 'Should interact with upgraded function in contract MyTokenV2 #group1': function (browser: NightwatchBrowser) {
browser browser
.clickInstance(1) .clickInstance(1)
.perform((done) => { .perform((done) => {
@ -168,7 +196,7 @@ module.exports = {
}) })
}, },
'Should upgrade contract by providing proxy address in input field (MyTokenV1 to MyTokenV2)': function (browser: NightwatchBrowser) { 'Should upgrade contract by providing proxy address in input field (MyTokenV1 to MyTokenV2) #group1': function (browser: NightwatchBrowser) {
browser browser
.waitForElementPresent('[data-id="deployAndRunClearInstances"]') .waitForElementPresent('[data-id="deployAndRunClearInstances"]')
.click('[data-id="deployAndRunClearInstances"]') .click('[data-id="deployAndRunClearInstances"]')
@ -196,7 +224,7 @@ module.exports = {
.waitForElementPresent('[data-id="universalDappUiTitleExpander1"]') .waitForElementPresent('[data-id="universalDappUiTitleExpander1"]')
}, },
'Should interact with upgraded contract through provided proxy address': function (browser: NightwatchBrowser) { 'Should interact with upgraded contract through provided proxy address #group1': function (browser: NightwatchBrowser) {
browser browser
.clickInstance(1) .clickInstance(1)
.perform((done) => { .perform((done) => {
@ -208,6 +236,7 @@ module.exports = {
} }
} }
const sources = [ const sources = [
{ {
'myTokenV1.sol': { 'myTokenV1.sol': {

@ -80,7 +80,7 @@ module.exports = {
'Should remember choice after page refresh': function (browser: NightwatchBrowser) { 'Should remember choice after page refresh': function (browser: NightwatchBrowser) {
browser browser
.refresh() .refreshPage()
.waitForElementVisible('[data-id="treeViewLitreeViewItemcontracts"]') .waitForElementVisible('[data-id="treeViewLitreeViewItemcontracts"]')
.click('[data-id="treeViewLitreeViewItemcontracts"]') .click('[data-id="treeViewLitreeViewItemcontracts"]')
.openFile('contracts/1_Storage.sol') .openFile('contracts/1_Storage.sol')

@ -15,7 +15,10 @@ module.exports = {
'Run Scenario #group1': function (browser: NightwatchBrowser) { 'Run Scenario #group1': function (browser: NightwatchBrowser) {
let addressRef let addressRef
browser.addFile('scenario.json', { content: records }) browser.addFile('scenario.json', { content: records })
.pause(5000) .waitForElementVisible({
locateStrategy: 'xpath',
selector: "//*[contains(@class, 'view-lines') and contains(.,'0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c')]"
})
.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="udappRecorderTitleExpander"]') .click('[data-id="udappRecorderTitleExpander"]')

@ -109,7 +109,7 @@ module.exports = {
.click('.network-indicator__down-arrow') .click('.network-indicator__down-arrow')
.useXpath().click("//span[text()='Goerli Test Network']") .useXpath().click("//span[text()='Goerli Test Network']")
.useCss().switchBrowserTab(0) .useCss().switchBrowserTab(0)
.refresh() .refreshPage()
.waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000) .waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000)
.click('*[data-id="landingPageStartSolidity"]') .click('*[data-id="landingPageStartSolidity"]')
.pause(5000) .pause(5000)
@ -165,7 +165,7 @@ module.exports = {
.click('.network-indicator__down-arrow') .click('.network-indicator__down-arrow')
.useXpath().click("//span[text()='Main Ethereum Network']") .useXpath().click("//span[text()='Main Ethereum Network']")
.useCss().switchBrowserTab(0) .useCss().switchBrowserTab(0)
.refresh() .refreshPage()
.waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000) .waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000)
.click('*[data-id="landingPageStartSolidity"]') .click('*[data-id="landingPageStartSolidity"]')
.pause(5000) .pause(5000)
@ -204,7 +204,7 @@ module.exports = {
.click('.network-indicator__down-arrow') .click('.network-indicator__down-arrow')
.useXpath().click("//span[text()='Ropsten Test Network']") // switch to Ropsten .useXpath().click("//span[text()='Ropsten Test Network']") // switch to Ropsten
.useCss().switchBrowserTab(0) .useCss().switchBrowserTab(0)
.refresh() .refreshPage()
.clickLaunchIcon('pluginManager') // load debugger and source verification .clickLaunchIcon('pluginManager') // load debugger and source verification
// .scrollAndClick('#pluginManager article[id="remixPluginManagerListItem_sourcify"] button') // .scrollAndClick('#pluginManager article[id="remixPluginManagerListItem_sourcify"] button')
// debugger already activated .scrollAndClick('#pluginManager article[id="remixPluginManagerListItem_debugger"] button') // debugger already activated .scrollAndClick('#pluginManager article[id="remixPluginManagerListItem_debugger"] button')

@ -27,7 +27,27 @@ module.exports = {
'Test Failed Import #group1': function (browser: NightwatchBrowser) { 'Test Failed Import #group1': function (browser: NightwatchBrowser) {
browser.addFile('Untitled3.sol', sources[2]['Untitled3.sol']) browser.addFile('Untitled3.sol', sources[2]['Untitled3.sol'])
.clickLaunchIcon('solidity') .clickLaunchIcon('solidity')
.assert.containsText('#compileTabView .error pre', 'not found Untitled11.sol') .click('[data-id="compilerContainerCompileBtn"]')
.isVisible({
selector: "//span[contains(.,'not found Untitled11')]",
locateStrategy: 'xpath',
timeout: 120000,
suppressNotFoundErrors: true
})
.click('[data-id="compilerContainerCompileBtn"]')
.isVisible({
selector: "//span[contains(.,'not found Untitled11')]",
locateStrategy: 'xpath',
timeout: 120000,
suppressNotFoundErrors: true
})
.click('[data-id="compilerContainerCompileBtn"]')
.waitForElementVisible({
selector: "//span[contains(.,'not found Untitled11')]",
locateStrategy: 'xpath',
timeout: 120000,
})
}, },
'Test GitHub Import - from master branch #group1': function (browser: NightwatchBrowser) { 'Test GitHub Import - from master branch #group1': function (browser: NightwatchBrowser) {

@ -291,9 +291,11 @@ module.exports = {
.goToVMTraceStep(316) .goToVMTraceStep(316)
.waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinningProposalFailed()', 60000) .waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinningProposalFailed()', 60000)
.waitForElementContainsText('*[data-id="functionPanel"]', 'vote(proposal)', 60000) .waitForElementContainsText('*[data-id="functionPanel"]', 'vote(proposal)', 60000)
.pause(5000) .waitForElementVisible({
locateStrategy: 'xpath',
selector: "//*[@data-id='treeViewDivtreeViewItemsender' and contains(.,'Ballot.Voter')]"
})
.checkVariableDebug('soliditylocals', locals) .checkVariableDebug('soliditylocals', locals)
.pause(5000)
.clickLaunchIcon('solidityUnitTesting').pause(2000) .clickLaunchIcon('solidityUnitTesting').pause(2000)
.scrollAndClick('#Check_winning_proposal_passed') .scrollAndClick('#Check_winning_proposal_passed')
.waitForElementContainsText('*[data-id="sidePanelSwapitTitle"]', 'DEBUGGER', 60000) .waitForElementContainsText('*[data-id="sidePanelSwapitTitle"]', 'DEBUGGER', 60000)
@ -303,17 +305,19 @@ module.exports = {
.waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinningProposalPassed()', 60000) .waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinningProposalPassed()', 60000)
// remix_test.sol should be opened in editor // remix_test.sol should be opened in editor
.getEditorValue((content) => browser.assert.ok(content.indexOf('library Assert {') !== -1)) .getEditorValue((content) => browser.assert.ok(content.indexOf('library Assert {') !== -1))
.pause(5000) .clickLaunchIcon('solidityUnitTesting')
.clickLaunchIcon('solidityUnitTesting').pause(2000) .waitForElementPresent('#Check_winning_proposal_again')
.scrollAndClick('#Check_winning_proposal_again') .scrollAndClick('#Check_winning_proposal_again')
.waitForElementContainsText('*[data-id="sidePanelSwapitTitle"]', 'DEBUGGER', 60000) .waitForElementContainsText('*[data-id="sidePanelSwapitTitle"]', 'DEBUGGER', 60000)
.waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinningProposalAgain()', 60000) .waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinningProposalAgain()', 60000)
.goToVMTraceStep(1151) .goToVMTraceStep(1151)
.waitForElementContainsText('*[data-id="functionPanel"]', 'equal(a, b, message)', 60000) .waitForElementContainsText('*[data-id="functionPanel"]', 'equal(a, b, message)', 60000)
.waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinningProposalAgain()', 60000) .waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinningProposalAgain()', 60000)
//.pause(5000)
.clickLaunchIcon('solidityUnitTesting')
.pause(5000)
.scrollAndClick('#Check_winnin_proposal_with_return_value')
.pause(5000) .pause(5000)
.clickLaunchIcon('solidityUnitTesting').pause(5000)
.scrollAndClick('#Check_winnin_proposal_with_return_value').pause(5000)
.waitForElementContainsText('*[data-id="sidePanelSwapitTitle"]', 'DEBUGGER', 60000) .waitForElementContainsText('*[data-id="sidePanelSwapitTitle"]', 'DEBUGGER', 60000)
.waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinninProposalWithReturnValue()', 60000) .waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinninProposalWithReturnValue()', 60000)
.goToVMTraceStep(321) .goToVMTraceStep(321)

@ -182,7 +182,7 @@ module.exports = {
done() done()
}) })
.pause(10000) .pause(10000)
.refresh() .refreshPage()
.perform(done => checkContent(0, done)) .perform(done => checkContent(0, done))
.perform(done => checkContent(1, done)) .perform(done => checkContent(1, done))
.perform(done => checkContent(2, done)) .perform(done => checkContent(2, done))

@ -164,6 +164,8 @@ module.exports = {
}, },
'Should print hardhat logs #group4': function (browser: NightwatchBrowser) { 'Should print hardhat logs #group4': function (browser: NightwatchBrowser) {
browser browser
.addFile('printHardhatlog.sol', { content: hardhatLog })
.clickLaunchIcon('solidity')
.click('*[data-id="terminalClearConsole"]') // clear the terminal .click('*[data-id="terminalClearConsole"]') // clear the terminal
.waitForElementVisible('[for="autoCompile"]') .waitForElementVisible('[for="autoCompile"]')
.click('[for="autoCompile"]') .click('[for="autoCompile"]')

@ -23,8 +23,6 @@ module.exports = {
status: 'true Transaction mined and execution succeed', status: 'true Transaction mined and execution succeed',
'decoded output': { 0: 'uint256: 8' } 'decoded output': { 0: 'uint256: 8' }
}) })
.pause(120000)
//.checkTerminalFilter('0x12332162e2e31397dc1e07ed0a1cf08f728e9b4487c6f9ed79d2f39410c92782', '')
.clickFunction('g - transact (not payable)') .clickFunction('g - transact (not payable)')
.testFunction('last', .testFunction('last',
{ {

@ -49,15 +49,17 @@ module.exports = {
'@sources': function () { '@sources': function () {
return sources return sources
}, },
'Disable auto compile': function (browser: NightwatchBrowser) {
'Should load the code from URL params (code param) #group1': function (browser: NightwatchBrowser) {
browser browser
.waitForElementVisible('[for="autoCompile"]') .waitForElementVisible('[for="autoCompile"]')
.click('[for="autoCompile"]') // we set it too false in the local storage .click('[for="autoCompile"]') // we set it too false in the local storage
.pause(5000) },
.url('http://127.0.0.1:8080/#autoCompile=true&optimize=true&runs=300&evmVersion=istanbul&version=soljson-v0.7.4+commit.3f05b770.js&code=cHJhZ21hIHNvbGlkaXR5ID49MC42LjAgPDAuNy4wOwoKaW1wb3J0ICJodHRwczovL2dpdGh1Yi5jb20vT3BlblplcHBlbGluL29wZW56ZXBwZWxpbi1jb250cmFjdHMvYmxvYi9tYXN0ZXIvY29udHJhY3RzL2FjY2Vzcy9Pd25hYmxlLnNvbCI7Cgpjb250cmFjdCBHZXRQYWlkIGlzIE93bmFibGUgewogIGZ1bmN0aW9uIHdpdGhkcmF3KCkgZXh0ZXJuYWwgb25seU93bmVyIHsKICB9Cn0') 'Should load the code from URL params (code param) #group1': function (browser: NightwatchBrowser) {
.refresh() // we do one reload for making sure we already have the default workspace browser
.pause(5000)
.url('http://127.0.0.1:8080/#autoCompile=true&optimize=true&runs=300&code=cHJhZ21hIHNvbGlkaXR5ID49MC42LjAgPDAuNy4wOwoKaW1wb3J0ICJodHRwczovL2dpdGh1Yi5jb20vT3BlblplcHBlbGluL29wZW56ZXBwZWxpbi1jb250cmFjdHMvYmxvYi9tYXN0ZXIvY29udHJhY3RzL2FjY2Vzcy9Pd25hYmxlLnNvbCI7Cgpjb250cmFjdCBHZXRQYWlkIGlzIE93bmFibGUgewogIGZ1bmN0aW9uIHdpdGhkcmF3KCkgZXh0ZXJuYWwgb25seU93bmVyIHsKICB9Cn0')
.refreshPage() // we do one reload for making sure we already have the default workspace
.verify.elementPresent('[data-id="compilerContainerAutoCompile"]:checked') .verify.elementPresent('[data-id="compilerContainerAutoCompile"]:checked')
.click('[for="autoCompile"]') // we set it too false again .click('[for="autoCompile"]') // we set it too false again
.click('[for="autoCompile"]') // back to True in the local storage .click('[for="autoCompile"]') // back to True in the local storage
@ -73,10 +75,13 @@ module.exports = {
'Should load the code from URL params (url param) #group1': function (browser: NightwatchBrowser) { 'Should load the code from URL params (url param) #group1': function (browser: NightwatchBrowser) {
browser browser
.pause(5000)
.url('http://127.0.0.1:8080/#optimize=true&runs=300&evmVersion=istanbul&version=soljson-v0.7.4+commit.3f05b770.js&url=https://github.com/ethereum/remix-project/blob/master/apps/remix-ide/contracts/app/solidity/mode.sol') .url('http://127.0.0.1:8080/#optimize=true&runs=300&url=https://github.com/ethereum/remix-project/blob/master/apps/remix-ide/contracts/app/solidity/mode.sol')
.refresh() // we do one reload for making sure we already have the default workspace .refreshPage() // we do one reload for making sure we already have the default workspace
.pause(5000) .waitForElementVisible({
selector: `//li[@data-id="treeViewLitreeViewItemethereum/remix-project/apps/remix-ide/contracts/app/solidity/mode.sol"]`,
locateStrategy: 'xpath'
})
.currentWorkspaceIs('code-sample') .currentWorkspaceIs('code-sample')
.getEditorValue((content) => { .getEditorValue((content) => {
browser.assert.ok(content && content.indexOf( browser.assert.ok(content && content.indexOf(
@ -87,10 +92,10 @@ module.exports = {
'Should load Etherscan verified contracts from URL "address" param)': !function (browser: NightwatchBrowser) { 'Should load Etherscan verified contracts from URL "address" param)': !function (browser: NightwatchBrowser) {
browser browser
.pause(5000)
.url('http://127.0.0.1:8080/#address=0x56db08fb78bc6689a1ef66efd079083fed0e4915') .url('http://127.0.0.1:8080/#address=0x56db08fb78bc6689a1ef66efd079083fed0e4915')
.refresh() .refreshPage()
.pause(7000)
.currentWorkspaceIs('etherscan-code-sample') .currentWorkspaceIs('etherscan-code-sample')
.assert.elementPresent('*[data-id=treeViewLitreeViewItemropsten]') .assert.elementPresent('*[data-id=treeViewLitreeViewItemropsten]')
.assert.elementPresent('*[data-id=treeViewLitreeViewItemrinkeby]') .assert.elementPresent('*[data-id=treeViewLitreeViewItemrinkeby]')
@ -101,7 +106,7 @@ module.exports = {
'contract Sample {') !== -1) 'contract Sample {') !== -1)
}) })
.url('http://127.0.0.1:8080/#address=0xdac17f958d2ee523a2206206994597c13d831ec7') .url('http://127.0.0.1:8080/#address=0xdac17f958d2ee523a2206206994597c13d831ec7')
.refresh() .refreshPage()
.pause(7000) .pause(7000)
.currentWorkspaceIs('etherscan-code-sample') .currentWorkspaceIs('etherscan-code-sample')
.assert.elementPresent('*[data-id=treeViewLitreeViewItemmainnet]') .assert.elementPresent('*[data-id=treeViewLitreeViewItemmainnet]')
@ -116,37 +121,33 @@ module.exports = {
'Should load the code from URL & code params #group1': function (browser: NightwatchBrowser) { 'Should load the code from URL & code params #group1': function (browser: NightwatchBrowser) {
browser browser
.pause(5000) .url('http://127.0.0.1:8080/#optimize=true&runs=300&url=https://github.com/ethereum/remix-project/blob/master/apps/remix-ide/contracts/app/solidity/mode.sol&code=cHJhZ21hIHNvbGlkaXR5ID49MC42LjAgPDAuNy4wOwoKaW1wb3J0ICJodHRwczovL2dpdGh1Yi5jb20vT3BlblplcHBlbGluL29wZW56ZXBwZWxpbi1jb250cmFjdHMvYmxvYi9tYXN0ZXIvY29udHJhY3RzL2FjY2Vzcy9Pd25hYmxlLnNvbCI7Cgpjb250cmFjdCBHZXRQYWlkIGlzIE93bmFibGUgewogIGZ1bmN0aW9uIHdpdGhkcmF3KCkgZXh0ZXJuYWwgb25seU93bmVyIHsKICB9Cn0')
.url('http://127.0.0.1:8080/#optimize=true&runs=300&evmVersion=istanbul&version=soljson-v0.7.4+commit.3f05b770.js&url=https://github.com/ethereum/remix-project/blob/master/apps/remix-ide/contracts/app/solidity/mode.sol&code=cHJhZ21hIHNvbGlkaXR5ID49MC42LjAgPDAuNy4wOwoKaW1wb3J0ICJodHRwczovL2dpdGh1Yi5jb20vT3BlblplcHBlbGluL29wZW56ZXBwZWxpbi1jb250cmFjdHMvYmxvYi9tYXN0ZXIvY29udHJhY3RzL2FjY2Vzcy9Pd25hYmxlLnNvbCI7Cgpjb250cmFjdCBHZXRQYWlkIGlzIE93bmFibGUgewogIGZ1bmN0aW9uIHdpdGhkcmF3KCkgZXh0ZXJuYWwgb25seU93bmVyIHsKICB9Cn0') .refreshPage() // we do one reload for making sure we already have the default workspace
.refresh() // we do one reload for making sure we already have the default workspace
.pause(5000) .waitForElementVisible('[data-id="compilerContainerCompileBtn"]')
.clickLaunchIcon('filePanel') .clickLaunchIcon('filePanel')
.waitForElementVisible({
selector: `//li[@data-id="treeViewLitreeViewItemethereum/remix-project/apps/remix-ide/contracts/app/solidity/mode.sol"]`,
locateStrategy: 'xpath'
})
.currentWorkspaceIs('code-sample') .currentWorkspaceIs('code-sample')
.getEditorValue((content) => { .getEditorValue((content) => {
browser.assert.ok(content && content.indexOf( browser.assert.ok(content && content.indexOf(
'proposals.length = _numProposals;') !== -1, 'proposals.length = _numProposals;') !== -1,
'code has not been loaded') 'code has been loaded')
}) })
.openFile('contract-76747f6e19.sol')
.openFile('ethereum')
.openFile('ethereum/remix-project')
.openFile('ethereum/remix-project/apps')
.openFile('ethereum/remix-project/apps/remix-ide')
.openFile('ethereum/remix-project/apps/remix-ide/contracts')
.openFile('ethereum/remix-project/apps/remix-ide/contracts/app')
.openFile('ethereum/remix-project/apps/remix-ide/contracts/app/solidity')
.openFile('ethereum/remix-project/apps/remix-ide/contracts/app/solidity/mode.sol')
}, },
'Should load the code from language & code params #group1': function (browser: NightwatchBrowser) { 'Should load the code from language & code params #group1': function (browser: NightwatchBrowser) {
browser browser
.pause(5000)
.url('http://127.0.0.1:8080/#language=yul&version=soljson-v0.8.7+commit.e28d00a7.js&code=Ly8gQSBjb250cmFjdCBjb25zaXN0cyBvZiBhIHNpbmdsZSBvYmplY3Qgd2l0aCBzdWItb2JqZWN0cyByZXByZXNlbnRpbmcKLy8gdGhlIGNvZGUgdG8gYmUgZGVwbG95ZWQgb3Igb3RoZXIgY29udHJhY3RzIGl0IGNhbiBjcmVhdGUuCi8vIFRoZSBzaW5nbGUgImNvZGUiIG5vZGUgaXMgdGhlIGV4ZWN1dGFibGUgY29kZSBvZiB0aGUgb2JqZWN0LgovLyBFdmVyeSAob3RoZXIpIG5hbWVkIG9iamVjdCBvciBkYXRhIHNlY3Rpb24gaXMgc2VyaWFsaXplZCBhbmQKLy8gbWFkZSBhY2Nlc3NpYmxlIHRvIHRoZSBzcGVjaWFsIGJ1aWx0LWluIGZ1bmN0aW9ucyBkYXRhY29weSAvIGRhdGFvZmZzZXQgLyBkYXRhc2l6ZQovLyBUaGUgY3VycmVudCBvYmplY3QsIHN1Yi1vYmplY3RzIGFuZCBkYXRhIGl0ZW1zIGluc2lkZSB0aGUgY3VycmVudCBvYmplY3QKLy8gYXJlIGluIHNjb3BlLgpvYmplY3QgIkNvbnRyYWN0MSIgewogICAgLy8gVGhpcyBpcyB0aGUgY29uc3RydWN0b3IgY29kZSBvZiB0aGUgY29udHJhY3QuCiAgICBjb2RlIHsKICAgICAgICBmdW5jdGlvbiBhbGxvY2F0ZShzaXplKSAtPiBwdHIgewogICAgICAgICAgICBwdHIgOj0gbWxvYWQoMHg0MCkKICAgICAgICAgICAgaWYgaXN6ZXJvKHB0cikgeyBwdHIgOj0gMHg2MCB9CiAgICAgICAgICAgIG1zdG9yZSgweDQwLCBhZGQocHRyLCBzaXplKSkKICAgICAgICB9CgogICAgICAgIC8vIGZpcnN0IGNyZWF0ZSAiQ29udHJhY3QyIgogICAgICAgIGxldCBzaXplIDo9IGRhdGFzaXplKCJDb250cmFjdDIiKQogICAgICAgIGxldCBvZmZzZXQgOj0gYWxsb2NhdGUoc2l6ZSkKICAgICAgICAvLyBUaGlzIHdpbGwgdHVybiBpbnRvIGNvZGVjb3B5IGZvciBFVk0KICAgICAgICBkYXRhY29weShvZmZzZXQsIGRhdGFvZmZzZXQoIkNvbnRyYWN0MiIpLCBzaXplKQogICAgICAgIC8vIGNvbnN0cnVjdG9yIHBhcmFtZXRlciBpcyBhIHNpbmdsZSBudW1iZXIgMHgxMjM0CiAgICAgICAgbXN0b3JlKGFkZChvZmZzZXQsIHNpemUpLCAweDEyMzQpCiAgICAgICAgcG9wKGNyZWF0ZShvZmZzZXQsIGFkZChzaXplLCAzMiksIDApKQoKICAgICAgICAvLyBub3cgcmV0dXJuIHRoZSBydW50aW1lIG9iamVjdCAodGhlIGN1cnJlbnRseQogICAgICAgIC8vIGV4ZWN1dGluZyBjb2RlIGlzIHRoZSBjb25zdHJ1Y3RvciBjb2RlKQogICAgICAgIHNpemUgOj0gZGF0YXNpemUoIkNvbnRyYWN0MV9kZXBsb3llZCIpCiAgICAgICAgb2Zmc2V0IDo9IGFsbG9jYXRlKHNpemUpCiAgICAgICAgLy8gVGhpcyB3aWxsIHR1cm4gaW50byBhIG1lbW9yeS0+bWVtb3J5IGNvcHkgZm9yIEV3YXNtIGFuZAogICAgICAgIC8vIGEgY29kZWNvcHkgZm9yIEVWTQogICAgICAgIGRhdGFjb3B5KG9mZnNldCwgZGF0YW9mZnNldCgiQ29udHJhY3QxX2RlcGxveWVkIiksIHNpemUpCiAgICAgICAgcmV0dXJuKG9mZnNldCwgc2l6ZSkKICAgIH0KCiAgICBkYXRhICJUYWJsZTIiIGhleCI0MTIzIgoKICAgIG9iamVjdCAiQ29udHJhY3QxX2RlcGxveWVkIiB7CiAgICAgICAgY29kZSB7CiAgICAgICAgICAgIGZ1bmN0aW9uIGFsbG9jYXRlKHNpemUpIC0+IHB0ciB7CiAgICAgICAgICAgICAgICBwdHIgOj0gbWxvYWQoMHg0MCkKICAgICAgICAgICAgICAgIGlmIGlzemVybyhwdHIpIHsgcHRyIDo9IDB4NjAgfQogICAgICAgICAgICAgICAgbXN0b3JlKDB4NDAsIGFkZChwdHIsIHNpemUpKQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBydW50aW1lIGNvZGUKCiAgICAgICAgICAgIG1zdG9yZSgwLCAiSGVsbG8sIFdvcmxkISIpCiAgICAgICAgICAgIHJldHVybigwLCAweDIwKQogICAgICAgIH0KICAgIH0KCiAgICAvLyBFbWJlZGRlZCBvYmplY3QuIFVzZSBjYXNlIGlzIHRoYXQgdGhlIG91dHNpZGUgaXMgYSBmYWN0b3J5IGNvbnRyYWN0LAogICAgLy8gYW5kIENvbnRyYWN0MiBpcyB0aGUgY29kZSB0byBiZSBjcmVhdGVkIGJ5IHRoZSBmYWN0b3J5CiAgICBvYmplY3QgIkNvbnRyYWN0MiIgewogICAgICAgIGNvZGUgewogICAgICAgICAgICAvLyBjb2RlIGhlcmUgLi4uCiAgICAgICAgfQoKICAgICAgICBvYmplY3QgIkNvbnRyYWN0Ml9kZXBsb3llZCIgewogICAgICAgICAgICBjb2RlIHsKICAgICAgICAgICAgICAgIC8vIGNvZGUgaGVyZSAuLi4KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZGF0YSAiVGFibGUxIiBoZXgiNDEyMyIKICAgIH0KfQ&optimize=false&runs=200&evmVersion=null') .url('http://127.0.0.1:8080/#language=yul&code=Ly8gQSBjb250cmFjdCBjb25zaXN0cyBvZiBhIHNpbmdsZSBvYmplY3Qgd2l0aCBzdWItb2JqZWN0cyByZXByZXNlbnRpbmcKLy8gdGhlIGNvZGUgdG8gYmUgZGVwbG95ZWQgb3Igb3RoZXIgY29udHJhY3RzIGl0IGNhbiBjcmVhdGUuCi8vIFRoZSBzaW5nbGUgImNvZGUiIG5vZGUgaXMgdGhlIGV4ZWN1dGFibGUgY29kZSBvZiB0aGUgb2JqZWN0LgovLyBFdmVyeSAob3RoZXIpIG5hbWVkIG9iamVjdCBvciBkYXRhIHNlY3Rpb24gaXMgc2VyaWFsaXplZCBhbmQKLy8gbWFkZSBhY2Nlc3NpYmxlIHRvIHRoZSBzcGVjaWFsIGJ1aWx0LWluIGZ1bmN0aW9ucyBkYXRhY29weSAvIGRhdGFvZmZzZXQgLyBkYXRhc2l6ZQovLyBUaGUgY3VycmVudCBvYmplY3QsIHN1Yi1vYmplY3RzIGFuZCBkYXRhIGl0ZW1zIGluc2lkZSB0aGUgY3VycmVudCBvYmplY3QKLy8gYXJlIGluIHNjb3BlLgpvYmplY3QgIkNvbnRyYWN0MSIgewogICAgLy8gVGhpcyBpcyB0aGUgY29uc3RydWN0b3IgY29kZSBvZiB0aGUgY29udHJhY3QuCiAgICBjb2RlIHsKICAgICAgICBmdW5jdGlvbiBhbGxvY2F0ZShzaXplKSAtPiBwdHIgewogICAgICAgICAgICBwdHIgOj0gbWxvYWQoMHg0MCkKICAgICAgICAgICAgaWYgaXN6ZXJvKHB0cikgeyBwdHIgOj0gMHg2MCB9CiAgICAgICAgICAgIG1zdG9yZSgweDQwLCBhZGQocHRyLCBzaXplKSkKICAgICAgICB9CgogICAgICAgIC8vIGZpcnN0IGNyZWF0ZSAiQ29udHJhY3QyIgogICAgICAgIGxldCBzaXplIDo9IGRhdGFzaXplKCJDb250cmFjdDIiKQogICAgICAgIGxldCBvZmZzZXQgOj0gYWxsb2NhdGUoc2l6ZSkKICAgICAgICAvLyBUaGlzIHdpbGwgdHVybiBpbnRvIGNvZGVjb3B5IGZvciBFVk0KICAgICAgICBkYXRhY29weShvZmZzZXQsIGRhdGFvZmZzZXQoIkNvbnRyYWN0MiIpLCBzaXplKQogICAgICAgIC8vIGNvbnN0cnVjdG9yIHBhcmFtZXRlciBpcyBhIHNpbmdsZSBudW1iZXIgMHgxMjM0CiAgICAgICAgbXN0b3JlKGFkZChvZmZzZXQsIHNpemUpLCAweDEyMzQpCiAgICAgICAgcG9wKGNyZWF0ZShvZmZzZXQsIGFkZChzaXplLCAzMiksIDApKQoKICAgICAgICAvLyBub3cgcmV0dXJuIHRoZSBydW50aW1lIG9iamVjdCAodGhlIGN1cnJlbnRseQogICAgICAgIC8vIGV4ZWN1dGluZyBjb2RlIGlzIHRoZSBjb25zdHJ1Y3RvciBjb2RlKQogICAgICAgIHNpemUgOj0gZGF0YXNpemUoIkNvbnRyYWN0MV9kZXBsb3llZCIpCiAgICAgICAgb2Zmc2V0IDo9IGFsbG9jYXRlKHNpemUpCiAgICAgICAgLy8gVGhpcyB3aWxsIHR1cm4gaW50byBhIG1lbW9yeS0+bWVtb3J5IGNvcHkgZm9yIEV3YXNtIGFuZAogICAgICAgIC8vIGEgY29kZWNvcHkgZm9yIEVWTQogICAgICAgIGRhdGFjb3B5KG9mZnNldCwgZGF0YW9mZnNldCgiQ29udHJhY3QxX2RlcGxveWVkIiksIHNpemUpCiAgICAgICAgcmV0dXJuKG9mZnNldCwgc2l6ZSkKICAgIH0KCiAgICBkYXRhICJUYWJsZTIiIGhleCI0MTIzIgoKICAgIG9iamVjdCAiQ29udHJhY3QxX2RlcGxveWVkIiB7CiAgICAgICAgY29kZSB7CiAgICAgICAgICAgIGZ1bmN0aW9uIGFsbG9jYXRlKHNpemUpIC0+IHB0ciB7CiAgICAgICAgICAgICAgICBwdHIgOj0gbWxvYWQoMHg0MCkKICAgICAgICAgICAgICAgIGlmIGlzemVybyhwdHIpIHsgcHRyIDo9IDB4NjAgfQogICAgICAgICAgICAgICAgbXN0b3JlKDB4NDAsIGFkZChwdHIsIHNpemUpKQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBydW50aW1lIGNvZGUKCiAgICAgICAgICAgIG1zdG9yZSgwLCAiSGVsbG8sIFdvcmxkISIpCiAgICAgICAgICAgIHJldHVybigwLCAweDIwKQogICAgICAgIH0KICAgIH0KCiAgICAvLyBFbWJlZGRlZCBvYmplY3QuIFVzZSBjYXNlIGlzIHRoYXQgdGhlIG91dHNpZGUgaXMgYSBmYWN0b3J5IGNvbnRyYWN0LAogICAgLy8gYW5kIENvbnRyYWN0MiBpcyB0aGUgY29kZSB0byBiZSBjcmVhdGVkIGJ5IHRoZSBmYWN0b3J5CiAgICBvYmplY3QgIkNvbnRyYWN0MiIgewogICAgICAgIGNvZGUgewogICAgICAgICAgICAvLyBjb2RlIGhlcmUgLi4uCiAgICAgICAgfQoKICAgICAgICBvYmplY3QgIkNvbnRyYWN0Ml9kZXBsb3llZCIgewogICAgICAgICAgICBjb2RlIHsKICAgICAgICAgICAgICAgIC8vIGNvZGUgaGVyZSAuLi4KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZGF0YSAiVGFibGUxIiBoZXgiNDEyMyIKICAgIH0KfQ&optimize=false&runs=200&evmVersion=null')
.refresh() .refreshPage()
.pause(5000) .waitForElementVisible('[data-id="compilerContainerCompileBtn"]')
.clickLaunchIcon('filePanel') .clickLaunchIcon('filePanel')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemcontract-eaa022e37e.yul"]')
.currentWorkspaceIs('code-sample') .currentWorkspaceIs('code-sample')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemcontract-eaa022e37e.yul"]', 6000)
.openFile('contract-eaa022e37e.yul') .openFile('contract-eaa022e37e.yul')
.getEditorValue((content) => { .getEditorValue((content) => {
browser.assert.ok(content && content.indexOf( browser.assert.ok(content && content.indexOf(
@ -154,16 +155,37 @@ module.exports = {
}) })
}, },
'Should select deploy with proxy option from URL params #group1': function (browser: NightwatchBrowser) { 'Should select deploy with proxy option from URL params #group2': function (browser: NightwatchBrowser) {
browser browser
.url('http://127.0.0.1:8080/#optimize=false&runs=200&deployProxy=true') .url('http://127.0.0.1:8080/#optimize=false&runs=200&deployProxy=true')
.refresh() .refreshPage()
.pause(5000)
.switchWorkspace('default_workspace') .switchWorkspace('default_workspace')
.addFile('myTokenV1.sol', sources[1]['myTokenV1.sol']) .addFile('myTokenV1.sol', sources[1]['myTokenV1.sol'])
.clickLaunchIcon('solidity') .clickLaunchIcon('solidity')
.pause(2000) .pause(2000)
.click('[data-id="compilerContainerCompileBtn"]') .click('[data-id="compilerContainerCompileBtn"]')
.clickLaunchIcon('filePanel')
.isVisible({
selector: '*[data-id="treeViewDivtreeViewItem.deps/npm/@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol"]',
timeout: 120000,
suppressNotFoundErrors: true
})
.clickLaunchIcon('solidity')
.click('[data-id="compilerContainerCompileBtn"]')
.clickLaunchIcon('filePanel')
.isVisible({
selector: '*[data-id="treeViewDivtreeViewItem.deps/npm/@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol"]',
timeout: 120000,
suppressNotFoundErrors: true
})
.clickLaunchIcon('solidity')
.click('[data-id="compilerContainerCompileBtn"]')
.clickLaunchIcon('filePanel')
.waitForElementVisible({
selector: '*[data-id="treeViewDivtreeViewItem.deps/npm/@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol"]',
timeout: 120000,
})
.clickLaunchIcon('solidity')
.waitForElementPresent('select[id="compiledContracts"] option[value=MyToken]', 60000) .waitForElementPresent('select[id="compiledContracts"] option[value=MyToken]', 60000)
.clickLaunchIcon('udapp') .clickLaunchIcon('udapp')
.click('select.udapp_contractNames') .click('select.udapp_contractNames')
@ -172,14 +194,18 @@ module.exports = {
.expect.element('[data-id="contractGUIDeployWithProxy"]').to.be.selected .expect.element('[data-id="contractGUIDeployWithProxy"]').to.be.selected
}, },
'Should select upgrade with proxy option from URL params #group1': function (browser: NightwatchBrowser) { 'Should select upgrade with proxy option from URL params #group2': function (browser: NightwatchBrowser) {
browser browser
.url('http://127.0.0.1:8080/#optimize=false&runs=200&upgradeProxy=true') .url('http://127.0.0.1:8080/#optimize=false&runs=200&upgradeProxy=true')
.refresh() .refreshPage()
.pause(5000) .waitForElementVisible('*[data-id="treeViewLitreeViewItemmyTokenV1.sol"]', 60000)
.openFile('myTokenV1.sol') .openFile('myTokenV1.sol')
.waitForElementVisible({
locateStrategy: 'xpath',
selector: "//*[contains(@class, 'view-lines') and contains(.,'ERC721Upgradeable')]"
})
.clickLaunchIcon('solidity') .clickLaunchIcon('solidity')
.pause(2000) .waitForElementVisible('[data-id="compilerContainerCompileBtn"]')
.click('[data-id="compilerContainerCompileBtn"]') .click('[data-id="compilerContainerCompileBtn"]')
.waitForElementPresent('select[id="compiledContracts"] option[value=MyToken]', 60000) .waitForElementPresent('select[id="compiledContracts"] option[value=MyToken]', 60000)
.clickLaunchIcon('udapp') .clickLaunchIcon('udapp')
@ -189,39 +215,42 @@ module.exports = {
.expect.element('[data-id="contractGUIUpgradeImplementation"]').to.be.selected .expect.element('[data-id="contractGUIUpgradeImplementation"]').to.be.selected
}, },
'Should load using various URL compiler params #group1': function (browser: NightwatchBrowser) { 'Should load using various URL compiler params #group2': function (browser: NightwatchBrowser) {
browser browser
.pause(5000)
.url('http://127.0.0.1:8080/#optimize=true&runs=300&autoCompile=true&evmVersion=istanbul&version=soljson-v0.7.4+commit.3f05b770.js&language=Yul') .url('http://127.0.0.1:8080/#optimize=true&runs=300&autoCompile=true&evmVersion=istanbul&version=soljson-v0.8.16+commit.07a7930e.js&language=Yul')
.refresh() .refreshPage()
.pause(5000)
.clickLaunchIcon('solidity') .clickLaunchIcon('solidity')
.click('*[data-id="scConfigExpander"]') .click('*[data-id="scConfigExpander"]')
.assert.containsText('#versionSelector option[data-id="selected"]', '0.7.4+commit.3f05b770') .waitForElementVisible('#versionSelector option[data-id="selected"]')
.assert.containsText('#versionSelector option[data-id="selected"]', '0.8.16+commit.07a7930e')
.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')
.verify.elementPresent('#optimize:checked') .verify.elementPresent('#optimize:checked')
.verify.elementPresent('#autoCompile:checked') .verify.elementPresent('#autoCompile:checked')
.verify.attributeEquals('#runs', 'value', '300') .verify.attributeEquals('#runs', 'value', '300')
.url('http://127.0.0.1:8080/#version=0.8.7') .url('http://127.0.0.1:8080/#version=0.8.7')
.refresh() .refreshPage()
.pause(5000)
.clickLaunchIcon('solidity') .clickLaunchIcon('solidity')
.waitForElementVisible('#versionSelector option[data-id="selected"]')
.assert.containsText('#versionSelector option[data-id="selected"]', '0.8.7+commit.e28d00a7') .assert.containsText('#versionSelector option[data-id="selected"]', '0.8.7+commit.e28d00a7')
.url('http://127.0.0.1:8080/#version=0.8.15+commit.e14f2714') .url('http://127.0.0.1:8080/#version=0.8.15+commit.e14f2714')
.refresh() .refreshPage()
.pause(5000) .pause(3000)
.clickLaunchIcon('solidity') .clickLaunchIcon('solidity')
.waitForElementVisible('#versionSelector option[data-id="selected"]')
.assert.containsText('#versionSelector option[data-id="selected"]', '0.8.15+commit.e14f2714') .assert.containsText('#versionSelector option[data-id="selected"]', '0.8.15+commit.e14f2714')
}, },
'Should load using compiler from link passed in remix URL #group1': function (browser: NightwatchBrowser) { 'Should load using compiler from link passed in remix URL #group3': function (browser: NightwatchBrowser) {
browser browser
.url('http://127.0.0.1:8080/#version=https://solidity-blog.s3.eu-central-1.amazonaws.com/data/08preview/soljson.js&optimize=false') .url('http://127.0.0.1:8080/#version=https://solidity-blog.s3.eu-central-1.amazonaws.com/data/08preview/soljson.js&optimize=false')
.refresh() .refreshPage()
.pause(5000)
.clickLaunchIcon('solidity') .clickLaunchIcon('solidity')
.pause(5000)
.click('*[data-id="scConfigExpander"]') .click('*[data-id="scConfigExpander"]')
.assert.containsText('#versionSelector option[data-id="selected"]', 'custom') .assert.containsText('#versionSelector option[data-id="selected"]', 'custom')
// default values // default values
@ -233,11 +262,11 @@ module.exports = {
.verify.attributeEquals('#runs', 'value', '200') .verify.attributeEquals('#runs', 'value', '200')
}, },
'Should load json files from link passed in remix URL #group1': function (browser: NightwatchBrowser) { 'Should load json files from link passed in remix URL #group3': function (browser: NightwatchBrowser) {
browser browser
.url('http://127.0.0.1:8080/#optimize=false&runs=200&evmVersion=null&version=soljson-v0.6.12+commit.27d51765.js&url=https://raw.githubusercontent.com/EthVM/evm-source-verification/main/contracts/1/0x011e5846975c6463a8c6337eecf3cbf64e328884/input.json') .url('http://127.0.0.1:8080/#optimize=false&runs=200&url=https://raw.githubusercontent.com/EthVM/evm-source-verification/main/contracts/1/0x011e5846975c6463a8c6337eecf3cbf64e328884/input.json')
.refresh() .refreshPage()
.pause(5000)
.switchWorkspace('code-sample') .switchWorkspace('code-sample')
.openFile('@openzeppelin') .openFile('@openzeppelin')
.openFile('@openzeppelin/contracts') .openFile('@openzeppelin/contracts')
@ -248,11 +277,11 @@ module.exports = {
.openFile('contracts/governance/UnionGovernor.sol') .openFile('contracts/governance/UnionGovernor.sol')
}, },
'Should execute function call from URL parameters #group1': function (browser: NightwatchBrowser) { 'Should execute function call from URL parameters #group3': function (browser: NightwatchBrowser) {
browser browser
.switchWorkspace('default_workspace') .switchWorkspace('default_workspace')
.url('http://127.0.0.1:8080?calls=fileManager//open//contracts/3_Ballot.sol///terminal//log//log') .url('http://127.0.0.1:8080?calls=fileManager//open//contracts/3_Ballot.sol///terminal//log//log')
.refresh() .refreshPage()
.waitForElementVisible('*[data-shared="tooltipPopup"]') .waitForElementVisible('*[data-shared="tooltipPopup"]')
.waitForElementContainsText('*[data-shared="tooltipPopup"]', 'initiating fileManager and calling "open" ...') .waitForElementContainsText('*[data-shared="tooltipPopup"]', 'initiating fileManager and calling "open" ...')
.waitForElementContainsText('*[data-shared="tooltipPopup"]', 'initiating terminal and calling "log" ...') .waitForElementContainsText('*[data-shared="tooltipPopup"]', 'initiating terminal and calling "log" ...')

@ -20,21 +20,22 @@ const sources = [
] ]
module.exports = { module.exports = {
'@disabled': true,
before: function (browser: NightwatchBrowser, done: VoidFunction) { before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done) init(browser, done)
}, },
'@sources': function () { '@sources': function () {
return sources return sources
}, },
'Using Web Worker': function (browser: NightwatchBrowser) { 'Using Web Worker #group1': function (browser: NightwatchBrowser) {
browser browser
.waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000) // using autocompile when switching compilers quickly confuses the process and results in a wrong compiler version being used or results displayed
.clickLaunchIcon('filePanel') .waitForElementVisible('[for="autoCompile"]')
.addFile('basic.sol', sources[0]['basic.sol']) .click('[for="autoCompile"]')
.clickLaunchIcon('solidity')
.waitForElementVisible('[data-id="compilerNightliesBuild"]') .waitForElementVisible('[data-id="compilerNightliesBuild"]')
.click('[data-id="compilerNightliesBuild"]') .click('[data-id="compilerNightliesBuild"]')
.noWorkerErrorFor('soljson-v0.3.4+commit.7dab8902.js') .addFile('basic.sol', sources[0]['basic.sol'])
.clickLaunchIcon('solidity')
.noWorkerErrorFor('soljson-v0.6.5+commit.f956cc89.js') .noWorkerErrorFor('soljson-v0.6.5+commit.f956cc89.js')
.noWorkerErrorFor('soljson-v0.6.8-nightly.2020.5.14+commit.a6d0067b.js') .noWorkerErrorFor('soljson-v0.6.8-nightly.2020.5.14+commit.a6d0067b.js')
.noWorkerErrorFor('soljson-v0.6.0-nightly.2019.12.17+commit.d13438ee.js') .noWorkerErrorFor('soljson-v0.6.0-nightly.2019.12.17+commit.d13438ee.js')

@ -19,7 +19,7 @@ module.exports = {
'Editor should be focused on the 3_Ballot.sol #group1': function (browser: NightwatchBrowser) { 'Editor should be focused on the 3_Ballot.sol #group1': function (browser: NightwatchBrowser) {
browser browser
.pause(5000) .pause(5000)
.refresh() .refreshPage()
.waitForElementVisible('#editorView', 30000) .waitForElementVisible('#editorView', 30000)
.getEditorValue((content) => { .getEditorValue((content) => {
browser.assert.ok(content.indexOf('contract Ballot {') !== -1, 'content includes Ballot contract') browser.assert.ok(content.indexOf('contract Ballot {') !== -1, 'content includes Ballot contract')

@ -27,6 +27,8 @@ declare module 'nightwatch' {
debugTransaction(index: number): NightwatchBrowser, debugTransaction(index: number): NightwatchBrowser,
checkElementStyle(cssSelector: string, styleProperty: string, expectedResult: string): NightwatchBrowser, checkElementStyle(cssSelector: string, styleProperty: string, expectedResult: string): NightwatchBrowser,
openFile(name: string): NightwatchBrowser, openFile(name: string): NightwatchBrowser,
refreshPage(): NightwatchBrowser,
verifyLoad(): NightwatchBrowser,
renamePath(path: string, newFileName: string, renamedPath: string): NightwatchBrowser, renamePath(path: string, newFileName: string, renamedPath: string): NightwatchBrowser,
rightClickCustom(cssSelector: string): NightwatchBrowser, rightClickCustom(cssSelector: string): NightwatchBrowser,
scrollToLine(line: number): NightwatchBrowser, scrollToLine(line: number): NightwatchBrowser,

@ -12,4 +12,5 @@ remix
TODO TODO
.tern-port .tern-port
temp_publish_docker temp_publish_docker
src/assets/version.json src/assets/version.json
src/assets/js/soljson-v*

@ -2,6 +2,8 @@
set -e set -e
BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}} BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}}
echo "$BUILD_ID" echo "$BUILD_ID"
TEST_EXITCODE=0 TEST_EXITCODE=0
@ -14,9 +16,12 @@ yarn run remixd &
sleep 5 sleep 5
yarn run build:e2e yarn run build:e2e
TESTFILES=$(grep -IRiL "@disabled" "dist/apps/remix-ide-e2e/src/tests" | grep "\.spec\|\.test" | sort | circleci tests split ) # grep -IRiL "@disabled" "dist/apps/remix-ide-e2e/src/tests" | grep "\.spec\|\.test" | xargs -I {} basename {} .test.js | grep -E "\b[${2}]"
# TESTFILES=$(grep -IRiL "@disabled" "dist/apps/remix-ide-e2e/src/tests" | grep "\.spec\|\.test" | xargs -I {} basename {} .test.js | grep -E "\b[$2]" | circleci tests split --split-by=timings )
node apps/remix-ide/ci/splice_tests.js $2 $3
TESTFILES=$(node apps/remix-ide/ci/splice_tests.js $2 $3 | circleci tests split --split-by=timings)
for TESTFILE in $TESTFILES; do for TESTFILE in $TESTFILES; do
npx nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js $TESTFILE --env=$1 || TEST_EXITCODE=1 npx nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/${TESTFILE}.js --env=$1 || TEST_EXITCODE=1
done done
echo "$TEST_EXITCODE" echo "$TEST_EXITCODE"

@ -6,6 +6,7 @@ BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}}
echo "$BUILD_ID" echo "$BUILD_ID"
TEST_EXITCODE=0 TEST_EXITCODE=0
yarn build etherscan
yarn run serve:production & yarn run serve:production &
npx nx serve etherscan & npx nx serve etherscan &

@ -6,6 +6,7 @@ BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}}
echo "$BUILD_ID" echo "$BUILD_ID"
TEST_EXITCODE=0 TEST_EXITCODE=0
yarn build vyper
yarn run serve:production & yarn run serve:production &
npx nx serve vyper & npx nx serve vyper &

@ -0,0 +1,63 @@
const testFolder = './apps/remix-ide-e2e/src/tests/';
const fs = require('fs');
let url = 'https://binaries.soliditylang.org/wasm/list.json'
const axios = require('axios')
// use axios to download the file
axios({
url: url,
method: 'GET',
}).then((response) => {
let info = response.data;
info.builds = info.builds.filter(build => build.path.indexOf('nightly') === -1)
for (let build of info.builds) {
const buildurl = `https://solc-bin.ethereum.org/wasm/${build.path}`;
console.log(buildurl)
const path = `./dist/apps/remix-ide/assets/js/${build.path}`;
// use axios to get the file
axios({
method: 'get',
url: buildurl,
responseType: 'stream'
}).then(function (response) {
// pipe the result stream into a file on disc
response.data.pipe(fs.createWriteStream(path));
})
}
}
)
fs.readdirSync(testFolder).forEach(file => {
let c = fs.readFileSync(testFolder + file, 'utf8');
const re = /(?<=soljson).*(?=(.js))/g;
const soljson = c.match(re);
if (soljson) {
for (let i = 0; i < soljson.length; i++) {
const version = soljson[i];
if (version && version.indexOf('nightly') > -1) {
const url = `https://solc-bin.ethereum.org/bin/soljson${version}.js`;
console.log(url)
const path = `./dist/apps/remix-ide/assets/js/soljson${version}.js`;
// use axios to get the file
axios({
method: 'get',
url: url,
responseType: 'stream'
}).then(function (response) {
// pipe the result stream into a file on disc
response.data.pipe(fs.createWriteStream(path));
})
}
}
}
});

@ -0,0 +1,27 @@
const fs = require('fs')
var exec = require('child_process').exec;
let cmd = `grep -IRiL "@disabled" "dist/apps/remix-ide-e2e/src/tests"`
// get command line arguments
let args = process.argv.slice(2)
const jobsize = args[0] || 10;
const job = args[1] || 0;
exec(cmd, (error, stdout, stderr) => {
if (error) {
console.error(`error: ${error.message}`);
return;
}
if (stderr) {
console.error(`stderr: ${stderr}`);
return;
}
let files = stdout.split('\n').filter(f => f.includes('.test')).map(f => f.replace('dist/apps/remix-ide-e2e/src/tests/', '')).map(f => f.replace('.js', ''))
let splitIndex = Math.ceil(files.length / jobsize);
const parts = []
for (let i = 0; i < jobsize; i++) {
parts.push(files.slice(i * splitIndex, (i + 1) * splitIndex))
}
console.log(parts[job].join('\n'))
});

@ -381,6 +381,10 @@ class AppComponent {
'filePanel', 'filePanel',
'workspaceInitializationCompleted', 'workspaceInitializationCompleted',
async () => { async () => {
// for e2e tests
const loadedElement = document.createElement('span')
loadedElement.setAttribute('data-id', 'workspaceloaded')
document.body.appendChild(loadedElement)
await this.appManager.registerContextMenuItems() await this.appManager.registerContextMenuItems()
} }
) )
@ -417,7 +421,7 @@ class AppComponent {
if (callDetails.length > 1) { if (callDetails.length > 1) {
this.appManager.call('notification', 'toast', `initiating ${callDetails[0]} and calling "${callDetails[1]}" ...`) this.appManager.call('notification', 'toast', `initiating ${callDetails[0]} and calling "${callDetails[1]}" ...`)
// @todo(remove the timeout when activatePlugin is on 0.3.0) // @todo(remove the timeout when activatePlugin is on 0.3.0)
this.appManager.call(...callDetails).catch(console.error) await this.appManager.call(...callDetails).catch(console.error)
} }
} }
@ -443,9 +447,15 @@ class AppComponent {
} }
} }
} }
}) })
.catch(console.error) .catch(console.error)
} }
const loadedElement = document.createElement('span')
loadedElement.setAttribute('data-id', 'apploaded')
document.body.appendChild(loadedElement)
}) })
// activate solidity plugin // activate solidity plugin
this.appManager.activatePlugin(['solidity', 'udapp', 'deploy-libraries', 'link-libraries', 'openzeppelin-proxy']) this.appManager.activatePlugin(['solidity', 'udapp', 'deploy-libraries', 'link-libraries', 'openzeppelin-proxy'])

@ -606,6 +606,10 @@ export const EditorUI = (props: EditorUIProps) => {
} }
return result return result
} }
// just for e2e testing
const loadedElement = document.createElement('span')
loadedElement.setAttribute('data-id', 'editorloaded')
document.body.appendChild(loadedElement)
} }
function handleEditorWillMount(monaco) { function handleEditorWillMount(monaco) {

@ -232,4 +232,8 @@ export const loadTypes = async (monaco) => {
// @ts-ignore // @ts-ignore
const mochaType = await import('raw-loader!@types/mocha/index.d.ts') const mochaType = await import('raw-loader!@types/mocha/index.d.ts')
monaco.languages.typescript.typescriptDefaults.addExtraLib(mochaType.default, `file:///node_modules/@types/mocha/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(mochaType.default, `file:///node_modules/@types/mocha/index.d.ts`)
const loadedElement = document.createElement('span')
loadedElement.setAttribute('data-id', 'typesloaded')
document.body.appendChild(loadedElement)
} }

@ -225,13 +225,13 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
if (state.useFileConfiguration) if (state.useFileConfiguration)
if (state.createFileOnce) { if (state.createFileOnce) {
api.fileExists(defaultPath).then((exists) => { api.fileExists(defaultPath).then((exists) => {
if (!exists || state.useFileConfiguration ) createNewConfigFile() if (!exists || state.useFileConfiguration) createNewConfigFile()
}) })
setState(prevState => { setState(prevState => {
return { ...prevState, createFileOnce: false } return { ...prevState, createFileOnce: false }
}) })
} }
setState(prevState => { setState(prevState => {
api.setAppParameter('useFileConfiguration', !state.useFileConfiguration) api.setAppParameter('useFileConfiguration', !state.useFileConfiguration)
return { ...prevState, useFileConfiguration: !state.useFileConfiguration } return { ...prevState, useFileConfiguration: !state.useFileConfiguration }
@ -239,7 +239,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
} }
const openFile = async () => { const openFile = async () => {
api.open(configFilePath) await api.open(configFilePath)
} }
const createNewConfigFile = async () => { const createNewConfigFile = async () => {
@ -279,7 +279,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
'Create', 'Create',
async () => await createNewConfigFile(), async () => await createNewConfigFile(),
'Cancel', 'Cancel',
() => { () => {
setShowFilePathInput(false) setShowFilePathInput(false)
} }
) )
@ -337,11 +337,13 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
if (allVersionsWasm && allVersions) { if (allVersionsWasm && allVersions) {
allVersions.forEach((compiler, index) => { allVersions.forEach((compiler, index) => {
const wasmIndex = allVersionsWasm.findIndex(wasmCompiler => { return wasmCompiler.longVersion === compiler.longVersion }) const wasmIndex = allVersionsWasm.findIndex(wasmCompiler => { return wasmCompiler.longVersion === compiler.longVersion })
const URLWasm: string = process && process.env && process.env['NX_WASM_URL'] ? process.env['NX_WASM_URL'] : baseURLWasm
const URLBin: string = process && process.env && process.env['NX_BIN_URL'] ? process.env['NX_BIN_URL'] : baseURLBin
if (wasmIndex !== -1) { if (wasmIndex !== -1) {
allVersions[index] = allVersionsWasm[wasmIndex] allVersions[index] = allVersionsWasm[wasmIndex]
pathToURL[compiler.path] = baseURLWasm pathToURL[compiler.path] = URLWasm
} else { } else {
pathToURL[compiler.path] = baseURLBin pathToURL[compiler.path] = URLBin
} }
}) })
} }
@ -434,7 +436,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
compileIcon.current.setAttribute('title', 'compiler is loading, please wait a few moments.') compileIcon.current.setAttribute('title', 'compiler is loading, please wait a few moments.')
compileIcon.current.classList.add('remixui_spinningIcon') compileIcon.current.classList.add('remixui_spinningIcon')
setState(prevState => { setState(prevState => {
return { ...prevState, compilerLicense: 'Compiler is loading. License will be displayed once compiler is loaded'} return { ...prevState, compilerLicense: 'Compiler is loading. License will be displayed once compiler is loaded' }
}) })
_updateLanguageSelector() _updateLanguageSelector()
setDisableCompileButton(true) setDisableCompileButton(true)
@ -451,6 +453,18 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
const isDisabled = !compiledFileName || (compiledFileName && !isSolFileSelected(compiledFileName)) const isDisabled = !compiledFileName || (compiledFileName && !isSolFileSelected(compiledFileName))
setDisableCompileButton(isDisabled) setDisableCompileButton(isDisabled)
// just for e2e
// eslint-disable-next-line no-case-declarations
const elements = document.querySelectorAll('[data-id="compilerloaded"]')
// remove elements
for (let i = 0; i < elements.length; i++) {
elements[i].remove()
}
const loadedElement = document.createElement('span')
loadedElement.setAttribute('data-id', 'compilerloaded')
loadedElement.setAttribute('data-version', state.selectedVersion)
document.body.appendChild(loadedElement)
} }
const compilationFinished = () => { const compilationFinished = () => {
@ -553,22 +567,22 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
const _shouldBeAdded = (version) => { const _shouldBeAdded = (version) => {
return !version.includes('nightly') || return !version.includes('nightly') ||
(version.includes('nightly') && state.includeNightlies) (version.includes('nightly') && state.includeNightlies)
} }
const promptCompiler = () => { const promptCompiler = () => {
// custom url https://solidity-blog.s3.eu-central-1.amazonaws.com/data/08preview/soljson.js // custom url https://solidity-blog.s3.eu-central-1.amazonaws.com/data/08preview/soljson.js
modal('Add a custom compiler', promptMessage('URL'), 'OK', addCustomCompiler, 'Cancel', () => {}) modal('Add a custom compiler', promptMessage('URL'), 'OK', addCustomCompiler, 'Cancel', () => { })
} }
const showCompilerLicense = () => { const showCompilerLicense = () => {
modal('Compiler License', state.compilerLicense ? state.compilerLicense : 'License not available', 'OK', () => {}) modal('Compiler License', state.compilerLicense ? state.compilerLicense : 'License not available', 'OK', () => { })
} }
const promptMessage = (message) => { const promptMessage = (message) => {
return ( return (
<> <>
<span>{ message }</span> <span>{message}</span>
<input type="text" data-id="modalDialogCustomPromptCompiler" className="form-control" ref={promptMessageInput} /> <input type="text" data-id="modalDialogCustomPromptCompiler" className="form-control" ref={promptMessageInput} />
</> </>
) )
@ -707,7 +721,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
setToggleExpander(!toggleExpander) setToggleExpander(!toggleExpander)
} }
return ( return (
<section> <section>
<article> <article>
<div className='pt-0 remixui_compilerSection'> <div className='pt-0 remixui_compilerSection'>
@ -715,11 +729,11 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
<label className="remixui_compilerLabel form-check-label" htmlFor="versionSelector">Compiler</label> <label className="remixui_compilerLabel form-check-label" htmlFor="versionSelector">Compiler</label>
<span className="far fa-plus border-0 p-0 ml-3" onClick={() => promptCompiler()} title="Add a custom compiler with URL"></span> <span className="far fa-plus border-0 p-0 ml-3" onClick={() => promptCompiler()} title="Add a custom compiler with URL"></span>
<span className="fa fa-file-text-o border-0 p-0 ml-2" onClick={() => showCompilerLicense()} title="See compiler license"></span> <span className="fa fa-file-text-o border-0 p-0 ml-2" onClick={() => showCompilerLicense()} title="See compiler license"></span>
<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>}
{ state.allversions.length <= 0 && <option disabled data-id={state.selectedVersion === 'builtin' ? 'selected' : ''}>builtin</option> } {state.allversions.length <= 0 && <option disabled data-id={state.selectedVersion === 'builtin' ? 'selected' : ''}>builtin</option>}
{ state.customVersions.map((url, i) => <option key={i} data-id={state.selectedVersion === url ? 'selected' : ''} value={url}>custom</option>)} {state.customVersions.map((url, i) => <option key={i} data-id={state.selectedVersion === url ? 'selected' : ''} value={url}>custom</option>)}
{ state.allversions.map((build, i) => { {state.allversions.map((build, i) => {
return _shouldBeAdded(build.longVersion) return _shouldBeAdded(build.longVersion)
? <option key={i} value={build.path} data-id={state.selectedVersion === build.path ? 'selected' : ''}>{build.longVersion}</option> ? <option key={i} value={build.path} data-id={state.selectedVersion === build.path ? 'selected' : ''}>{build.longVersion}</option>
: null : null
@ -824,12 +838,12 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
<label className="form-check-label custom-control-label" htmlFor="scFileConfig" data-id="scFileConfiguration">Use configuration file</label> <label className="form-check-label custom-control-label" htmlFor="scFileConfig" data-id="scFileConfiguration">Use configuration file</label>
</div> </div>
<div className={`pt-2 ml-4 ml-2 align-items-start justify-content-between d-flex`}> <div className={`pt-2 ml-4 ml-2 align-items-start justify-content-between d-flex`}>
{ (!showFilePathInput && state.useFileConfiguration) && <span {(!showFilePathInput && state.useFileConfiguration) && <span
title="Click to open the config file" title="Click to open the config file"
onClick={configFilePath === '' ? () => {} : openFile} onClick={configFilePath === '' ? () => { } : async () => { await openFile() }}
className="py-2 remixui_compilerConfigPath" className="py-2 remixui_compilerConfigPath"
>{configFilePath === '' ? 'No file selected.' : configFilePath}</span> } >{configFilePath === '' ? 'No file selected.' : configFilePath}</span>}
{ (!showFilePathInput && !state.useFileConfiguration) && <span className="py-2 text-secondary">{configFilePath}</span> } {(!showFilePathInput && !state.useFileConfiguration) && <span className="py-2 text-secondary">{configFilePath}</span>}
<input <input
ref={configFilePathInput} ref={configFilePathInput}
className={`py-0 my-0 form-control ${showFilePathInput ? "d-flex" : "d-none"}`} className={`py-0 my-0 form-control ${showFilePathInput ? "d-flex" : "d-none"}`}
@ -843,7 +857,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
} }
}} }}
/> />
{ !showFilePathInput && <button disabled={!state.useFileConfiguration} data-id="scConfigChangeFilePath" className="btn-secondary" onClick={() => {setShowFilePathInput(true)}}>Change</button> } {!showFilePathInput && <button disabled={!state.useFileConfiguration} data-id="scConfigChangeFilePath" className="btn-secondary" onClick={() => { setShowFilePathInput(true) }}>Change</button>}
</div> </div>
</div> </div>
<div className="px-4"> <div className="px-4">
@ -851,18 +865,18 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
<OverlayTrigger overlay={ <OverlayTrigger overlay={
<Tooltip id="overlay-tooltip-compile"> <Tooltip id="overlay-tooltip-compile">
<div className="text-left"> <div className="text-left">
{ !(configFilePath === '' && state.useFileConfiguration) && <div><b>Ctrl+S</b> for compiling</div> } {!(configFilePath === '' && state.useFileConfiguration) && <div><b>Ctrl+S</b> for compiling</div>}
{ (configFilePath === '' && state.useFileConfiguration) && <div> No config file selected</div> } {(configFilePath === '' && state.useFileConfiguration) && <div> No config file selected</div>}
</div> </div>
</Tooltip> </Tooltip>
}> }>
<span> <span>
{ <i ref={compileIcon} className="fas fa-sync remixui_iconbtn" aria-hidden="true"></i> } {<i ref={compileIcon} className="fas fa-sync remixui_iconbtn" aria-hidden="true"></i>}
Compile { typeof state.compiledFileName === 'string' ? extractNameFromKey(state.compiledFileName) || '<no file selected>' : '<no file selected>' } Compile {typeof state.compiledFileName === 'string' ? extractNameFromKey(state.compiledFileName) || '<no file selected>' : '<no file selected>'}
</span> </span>
</OverlayTrigger> </OverlayTrigger>
</button> </button>
<div className='d-flex align-items-center'> <div className='d-flex align-items-center'>
<button <button
id="compileAndRunBtn" id="compileAndRunBtn"
data-id="compilerContainerCompileAndRunBtn" data-id="compilerContainerCompileAndRunBtn"
@ -873,8 +887,8 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
<OverlayTrigger overlay={ <OverlayTrigger overlay={
<Tooltip id="overlay-tooltip-compile-run"> <Tooltip id="overlay-tooltip-compile-run">
<div className="text-left"> <div className="text-left">
{ !(configFilePath === '' && state.useFileConfiguration) && <div><b>Ctrl+Shift+S</b> for compiling and script execution</div> } {!(configFilePath === '' && state.useFileConfiguration) && <div><b>Ctrl+Shift+S</b> for compiling and script execution</div>}
{ (configFilePath === '' && state.useFileConfiguration) && <div> No config file selected</div> } {(configFilePath === '' && state.useFileConfiguration) && <div> No config file selected</div>}
</div> </div>
</Tooltip> </Tooltip>
}> }>
@ -882,7 +896,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
Compile and Run script Compile and Run script
</span> </span>
</OverlayTrigger> </OverlayTrigger>
</button> </button>
<OverlayTrigger overlay={ <OverlayTrigger overlay={
<Tooltip id="overlay-tooltip-compile-run-doc"> <Tooltip id="overlay-tooltip-compile-run-doc">
<div className="text-left p-2"> <div className="text-left p-2">
@ -890,11 +904,11 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
<pre> <pre>
<code> <code>
/**<br /> /**<br />
* @title ContractName<br /> * @title ContractName<br />
* @dev ContractDescription<br /> * @dev ContractDescription<br />
* @custom:dev-run-script file_path<br /> * @custom:dev-run-script file_path<br />
*/<br /> */<br />
contract ContractName {'{}'}<br /> contract ContractName {'{}'}<br />
</code> </code>
</pre> </pre>
Click to know more Click to know more
@ -909,7 +923,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
</button> </button>
</CopyToClipboard> </CopyToClipboard>
</div> </div>
</div> </div>
</article> </article>
</section> </section>
) )

@ -54,6 +54,7 @@
"bumpVersion:libs": "gulp & gulp syncLibVersions;", "bumpVersion:libs": "gulp & gulp syncLibVersions;",
"browsertest": "sleep 5 && yarn 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_e2e": "node ./apps/remix-ide/ci/download_e2e_assets.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": "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",
"make-mock-compiler": "node apps/remix-ide/ci/makeMockCompiler.js", "make-mock-compiler": "node apps/remix-ide/ci/makeMockCompiler.js",
@ -66,7 +67,7 @@
"nightwatch_local_firefox": "yarn 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": "yarn 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": "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": "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": "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_ballot_0_4_14": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/ballot_0_4_14.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_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": "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_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": "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_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",

Loading…
Cancel
Save