add e2e test

pull/2291/head^2
yann300 2 years ago committed by Aniket
parent 81023016cb
commit af911a75d9
  1. 50
      .circleci/config.yml
  2. 17
      apps/remix-ide-e2e/src/helpers/init.ts
  3. 96
      apps/remix-ide-e2e/src/tests/vyper_api.ts
  4. 25
      apps/remix-ide/ci/browser_tests_vyper_plugin.sh
  5. 4
      apps/remix-ide/src/remixAppManager.js
  6. 4
      apps/vyper/src/app/app.tsx
  7. 2
      apps/vyper/src/app/components/CompilerButton.tsx
  8. 4
      apps/vyper/src/app/components/VyperResult.tsx
  9. 2
      workspace.json

@ -267,6 +267,50 @@ jobs:
- store_artifacts: - store_artifacts:
path: ./reports/screenshots path: ./reports/screenshots
remix-ide-vyper-plugin:
docker:
# specify the version you desire here
- image: cimg/node:14.17.6-browsers
# 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:
- browser-tools/install-chrome
- browser-tools/install-chromedriver
- run:
command: |
google-chrome --version
chromedriver --version
java -jar /usr/local/bin/selenium.jar --version
name: Check install
- checkout
- checkout
- attach_workspace:
at: .
- run: unzip ./persist/dist.zip
- restore_cache:
keys:
- v1-deps-{{ checksum "yarn.lock" }}
- run: yarn install
- run:
name: Start Selenium
command: java -jar /usr/local/bin/selenium.jar
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-plugin-api: remix-ide-plugin-api:
docker: docker:
# specify the version you desire here # specify the version you desire here
@ -420,6 +464,9 @@ workflows:
- remix-ide-plugin-api: - remix-ide-plugin-api:
requires: requires:
- build - build
- remix-ide-vyper-plugin:
requires:
- build
- remix-ide-chrome: - remix-ide-chrome:
requires: requires:
- build - build
@ -433,6 +480,7 @@ workflows:
- remix-ide-chrome - remix-ide-chrome
- remix-ide-firefox - remix-ide-firefox
- remix-ide-plugin-api - remix-ide-plugin-api
- remix-ide-vyper-plugin
filters: filters:
branches: branches:
only: remix_live only: remix_live
@ -443,6 +491,7 @@ workflows:
- remix-ide-chrome - remix-ide-chrome
- remix-ide-firefox - remix-ide-firefox
- remix-ide-plugin-api - remix-ide-plugin-api
- remix-ide-vyper-plugin
filters: filters:
branches: branches:
only: master only: master
@ -453,6 +502,7 @@ workflows:
- remix-ide-chrome - remix-ide-chrome
- remix-ide-firefox - remix-ide-firefox
- remix-ide-plugin-api - remix-ide-plugin-api
- remix-ide-vyper-plugin
filters: filters:
branches: branches:
only: remix_beta only: remix_beta

@ -2,13 +2,28 @@ import { NightwatchBrowser } from 'nightwatch'
require('dotenv').config() require('dotenv').config()
export default function (browser: NightwatchBrowser, callback: VoidFunction, url?: string, preloadPlugins = true): void { type LoadPlugin = {
name: string
url: string
}
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) .pause(6000)
.switchBrowserTab(0) .switchBrowserTab(0)
.waitForElementVisible('[id="remixTourSkipbtn"]') .waitForElementVisible('[id="remixTourSkipbtn"]')
.click('[id="remixTourSkipbtn"]') .click('[id="remixTourSkipbtn"]')
.perform((done) => {
if (!loadPlugin) return done()
browser.execute(function (loadPlugin) { // override a plugin url for testing purpose
localStorage.setItem('test-plugin-name', loadPlugin.name)
localStorage.setItem('test-plugin-url', loadPlugin.url)
}, [loadPlugin])
.refresh()
.pause(6000)
.perform(done)
})
.maximizeWindow() .maximizeWindow()
.fullscreenWindow(() => { .fullscreenWindow(() => {
if (preloadPlugins) { if (preloadPlugins) {

@ -0,0 +1,96 @@
'use strict'
import { NightwatchBrowser } from 'nightwatch'
import init from '../helpers/init'
declare global {
interface Window { testplugin: { name: string, url: string }; }
}
module.exports = {
'@disabled': true,
before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done, null, true, { name: 'vyper', url: 'http://127.0.0.1:5002'})
},
'Should connect to vyper plugin #group1': function (browser: NightwatchBrowser) {
browser.clickLaunchIcon('pluginManager')
.scrollAndClick('[data-id="pluginManagerComponentActivateButtonvyper"]')
.clickLaunchIcon('vyper')
.pause(5000)
// @ts-ignore
.frame(0)
},
'Should add the Ballot.vy #group1': function (browser: NightwatchBrowser) {
browser.click('button[data-id="add-ballot"]')
.frameParent()
.openFile('ballot.vy')
},
'Compile ballot.vy should error #group1': function (browser: NightwatchBrowser) {
browser.clickLaunchIcon('vyper')
// @ts-ignore
.frame(0)
.click('[data-id="remote-compiler"]')
.click('[data-id="compile"]')
.assert.containsText('[data-id="error-message"]', 'unexpected indent')
},
'Compile test contract should success #group1': function (browser: NightwatchBrowser) {
let contractAddress
browser
.frameParent()
.addFile('test.vy', { content: testContract })
.clickLaunchIcon('vyper')
// @ts-ignore
.frame(0)
.click('[data-id="compile"]')
.frameParent()
.clickLaunchIcon('udapp')
.createContract('')
.clickInstance(0)
.clickFunction('totalPokemonCount - call')
.getAddressAtPosition(0, (address) => {
console.log('Vyper contract ' + address)
contractAddress = address
})
.perform((done) => {
browser.verifyCallReturnValue(contractAddress, ['0:uint256: 0'])
.perform(() => done())
})
}
}
const testContract = `
# @version >=0.2.4 <0.3.0
DNA_DIGITS: constant(uint256) = 16
DNA_MODULUS: constant(uint256) = 10 ** DNA_DIGITS
# add HP_LIMIT
struct Pokemon:
name: String[32]
dna: uint256
HP: uint256
matches: uint256
wins: uint256
totalPokemonCount: public(uint256)
pokemonList: HashMap[uint256, Pokemon]
@pure
@internal
def _generateRandomDNA(_name: String[32]) -> uint256:
random: uint256 = convert(keccak256(_name), uint256)
return random % DNA_MODULUS
# modify _createPokemon
@internal
def _createPokemon(_name: String[32], _dna: uint256, _HP: uint256):
self.pokemonList[self.totalPokemonCount] = Pokemon({
name: _name,
dna: _dna,
HP: _HP,
matches: 0,
wins: 0
})
self.totalPokemonCount += 1`

@ -0,0 +1,25 @@
#!/usr/bin/env bash
set -e
BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}}
echo "$BUILD_ID"
TEST_EXITCODE=0
yarn run serve:production &
npx nx serve vyper &
sleep 5
yarn run build:e2e
TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "vyper_api" | sort | circleci tests split )
for TESTFILE in $TESTFILES; do
npx nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js $TESTFILE --env=chrome || TEST_EXITCODE=1
done
echo "$TEST_EXITCODE"
if [ "$TEST_EXITCODE" -eq 1 ]
then
exit 1
fi

@ -146,9 +146,11 @@ export class RemixAppManager extends PluginManager {
} }
} }
} }
const testPluginName = localStorage.getItem('test-plugin-name')
const testPluginUrl = localStorage.getItem('test-plugin-url')
return plugins.map(plugin => { return plugins.map(plugin => {
if (plugin.name === testPluginName) plugin.url = testPluginUrl
return new IframePlugin(plugin) return new IframePlugin(plugin)
// return new IframeReactPlugin(plugin)
}) })
} }

@ -85,10 +85,10 @@ const App: React.FC = () => {
type="radio" type="radio"
value={state.environment} value={state.environment}
> >
<ToggleButton variant="secondary" name="remote" value="remote"> <ToggleButton data-id="remote-compiler" variant="secondary" name="remote" value="remote">
Remote Compiler Remote Compiler
</ToggleButton> </ToggleButton>
<ToggleButton variant="secondary" name="local" value="local"> <ToggleButton data-id="local-compiler" variant="secondary" name="local" value="local">
Local Compiler Local Compiler
</ToggleButton> </ToggleButton>
</ToggleButtonGroup> </ToggleButtonGroup>

@ -66,7 +66,7 @@ function CompilerButton({ contract, setOutput, compilerUrl }: Props) {
} }
return ( return (
<Button onClick={compileContract} variant="primary"> <Button data-id="compile" onClick={compileContract} variant="primary">
Compile {contract} Compile {contract}
</Button> </Button>
) )

@ -23,7 +23,7 @@ function VyperResult({ output }: VyperResultProps) {
if (!output) return ( if (!output) return (
<div id="result"> <div id="result">
<p>No contract compiled yet.</p> <p>No contract compiled yet.</p>
<Button variant="info" onClick={() => remixClient.loadContract(Ballot)}> <Button data-id="add-ballot" variant="info" onClick={() => remixClient.loadContract(Ballot)}>
Create Ballot.vy example Create Ballot.vy example
</Button> </Button>
</div> </div>
@ -33,7 +33,7 @@ function VyperResult({ output }: VyperResultProps) {
return ( return (
<div id="result" className="error"> <div id="result" className="error">
<i className="fas fa-exclamation-circle text-danger"></i> <i className="fas fa-exclamation-circle text-danger"></i>
<p className="alert alert-danger">{output.message}</p> <p data-id="error-message" className="alert alert-danger">{output.message}</p>
</div>) </div>)
} }

@ -1551,7 +1551,7 @@
"builder": "@nrwl/web:dev-server", "builder": "@nrwl/web:dev-server",
"options": { "options": {
"buildTarget": "vyper:build", "buildTarget": "vyper:build",
"hmr": true "port": 5002
}, },
"configurations": { "configurations": {
"production": { "production": {

Loading…
Cancel
Save