windows tests

pull/4837/head
bunsenstraat 8 months ago
parent c643b01b5c
commit 556bcf9f00
  1. 344
      apps/remixdesktop/nightwatch.conf.js
  2. 1
      apps/remixdesktop/package.json
  3. 10
      apps/remixdesktop/selenium-win.config.js
  4. 1
      apps/remixdesktop/src/main.ts
  5. 23
      apps/remixdesktop/test/nighwatch.app.ts
  6. 406
      apps/remixdesktop/test/tests/app/xterm.test.ts
  7. 243
      apps/remixdesktop/test/tests/app/xtermwin.test.ts
  8. 6
      libs/remix-ui/xterm/src/lib/components/remix-ui-terminal-menu-xterm.tsx

@ -0,0 +1,344 @@
//
// Refer to the online docs for more details:
// https://nightwatchjs.org/guide/configuration/nightwatch-configuration-file.html
//
// _ _ _ _ _ _ _
// | \ | |(_) | | | | | | | |
// | \| | _ __ _ | |__ | |_ __ __ __ _ | |_ ___ | |__
// | . ` || | / _` || '_ \ | __|\ \ /\ / / / _` || __| / __|| '_ \
// | |\ || || (_| || | | || |_ \ V V / | (_| || |_ | (__ | | | |
// \_| \_/|_| \__, ||_| |_| \__| \_/\_/ \__,_| \__| \___||_| |_|
// __/ |
// |___/
//
module.exports = {
// An array of folders (excluding subfolders) where your tests are located;
// if this is not specified, the test source must be passed as the second argument to the test runner.
src_folders: [],
// See https://nightwatchjs.org/guide/concepts/page-object-model.html
page_objects_path: ['node_modules/nightwatch/examples/pages/'],
// See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-commands.html
custom_commands_path: ['node_modules/nightwatch/examples/custom-commands/'],
// See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-assertions.html
custom_assertions_path: '',
// See https://nightwatchjs.org/guide/extending-nightwatch/adding-plugins.html
plugins: [],
// See https://nightwatchjs.org/guide/concepts/test-globals.html#external-test-globals
globals_path : '',
webdriver: {},
test_settings: {
default: {
disable_error_log: false,
launch_url: 'https://nightwatchjs.org',
screenshots: {
enabled: false,
path: 'screens',
on_failure: true
},
desiredCapabilities: {
browserName : 'firefox'
},
webdriver: {
start_process: true,
server_path: ''
}
},
firefox: {
desiredCapabilities : {
browserName : 'firefox',
alwaysMatch: {
acceptInsecureCerts: true,
'moz:firefoxOptions': {
args: [
// '-headless',
// '-verbose'
]
}
}
},
webdriver: {
start_process: true,
server_path: '',
cli_args: [
// very verbose geckodriver logs
// '-vv'
]
}
},
chrome: {
desiredCapabilities : {
browserName : 'chrome',
'goog:chromeOptions' : {
// More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/
//
// w3c:false tells Chromedriver to run using the legacy JSONWire protocol (not required in Chrome 78)
w3c: true,
args: [
//'--no-sandbox',
//'--ignore-certificate-errors',
//'--allow-insecure-localhost',
//'--headless'
]
}
},
webdriver: {
start_process: true,
server_path: '',
cli_args: [
// --verbose
]
}
},
edge: {
desiredCapabilities : {
browserName : 'MicrosoftEdge',
'ms:edgeOptions' : {
w3c: true,
// More info on EdgeDriver: https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/capabilities-edge-options
args: [
//'--headless'
]
}
},
webdriver: {
start_process: true,
// Download msedgedriver from https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/
// and set the location below:
server_path: '',
cli_args: [
// --verbose
]
}
},
//////////////////////////////////////////////////////////////////////////////////
// Configuration for when using cucumber-js (https://cucumber.io) |
// |
// It uses the bundled examples inside the nightwatch examples folder; feel free |
// to adapt this to your own project needs |
//////////////////////////////////////////////////////////////////////////////////
'cucumber-js': {
src_folders: ['examples/cucumber-js/features/step_definitions'],
test_runner: {
// set cucumber as the runner
type: 'cucumber',
// define cucumber specific options
options: {
//set the feature path
feature_path: 'node_modules/nightwatch/examples/cucumber-js/*/*.feature',
// start the webdriver session automatically (enabled by default)
// auto_start_session: true
// use parallel execution in Cucumber
// parallel: 2 // set number of workers to use (can also be defined in the cli as --parallel 2
}
}
},
//////////////////////////////////////////////////////////////////////////////////
// Configuration for when using the browserstack.com cloud service |
// |
// Please set the username and access key by setting the environment variables: |
// - BROWSERSTACK_USERNAME |
// - BROWSERSTACK_ACCESS_KEY |
// .env files are supported |
//////////////////////////////////////////////////////////////////////////////////
browserstack: {
selenium: {
host: 'hub.browserstack.com',
port: 443
},
// More info on configuring capabilities can be found on:
// https://www.browserstack.com/automate/capabilities?tag=selenium-4
desiredCapabilities: {
'bstack:options' : {
userName: '${BROWSERSTACK_USERNAME}',
accessKey: '${BROWSERSTACK_ACCESS_KEY}',
}
},
disable_error_log: true,
webdriver: {
timeout_options: {
timeout: 15000,
retry_attempts: 3
},
keep_alive: true,
start_process: false
}
},
'browserstack.local': {
extends: 'browserstack',
desiredCapabilities: {
'browserstack.local': true
}
},
'browserstack.chrome': {
extends: 'browserstack',
desiredCapabilities: {
browserName: 'chrome',
chromeOptions : {
w3c: true
}
}
},
'browserstack.firefox': {
extends: 'browserstack',
desiredCapabilities: {
browserName: 'firefox'
}
},
'browserstack.ie': {
extends: 'browserstack',
desiredCapabilities: {
browserName: 'internet explorer',
browserVersion: '11.0'
}
},
'browserstack.safari': {
extends: 'browserstack',
desiredCapabilities: {
browserName: 'safari'
}
},
'browserstack.local_chrome': {
extends: 'browserstack.local',
desiredCapabilities: {
browserName: 'chrome'
}
},
'browserstack.local_firefox': {
extends: 'browserstack.local',
desiredCapabilities: {
browserName: 'firefox'
}
},
//////////////////////////////////////////////////////////////////////////////////
// Configuration for when using the SauceLabs cloud service |
// |
// Please set the username and access key by setting the environment variables: |
// - SAUCE_USERNAME |
// - SAUCE_ACCESS_KEY |
//////////////////////////////////////////////////////////////////////////////////
saucelabs: {
selenium: {
host: 'ondemand.saucelabs.com',
port: 443
},
// More info on configuring capabilities can be found on:
// https://docs.saucelabs.com/dev/test-configuration-options/
desiredCapabilities: {
'sauce:options' : {
username: '${SAUCE_USERNAME}',
accessKey: '${SAUCE_ACCESS_KEY}',
screenResolution: '1280x1024'
// https://docs.saucelabs.com/dev/cli/sauce-connect-proxy/#--region
// region: 'us-west-1'
// https://docs.saucelabs.com/dev/test-configuration-options/#tunnelidentifier
// parentTunnel: '',
// tunnelIdentifier: '',
}
},
disable_error_log: false,
webdriver: {
start_process: false
}
},
'saucelabs.chrome': {
extends: 'saucelabs',
desiredCapabilities: {
browserName: 'chrome',
browserVersion: 'latest',
javascriptEnabled: true,
acceptSslCerts: true,
timeZone: 'London',
chromeOptions : {
w3c: true
}
}
},
'saucelabs.firefox': {
extends: 'saucelabs',
desiredCapabilities: {
browserName: 'firefox',
browserVersion: 'latest',
javascriptEnabled: true,
acceptSslCerts: true,
timeZone: 'London'
}
},
//////////////////////////////////////////////////////////////////////////////////
// Configuration for when using the Selenium service, either locally or remote, |
// like Selenium Grid |
//////////////////////////////////////////////////////////////////////////////////
selenium_server: {
// Selenium Server is running locally and is managed by Nightwatch
// Install the NPM package @nightwatch/selenium-server or download the selenium server jar file from https://github.com/SeleniumHQ/selenium/releases/, e.g.: selenium-server-4.1.1.jar
selenium: {
start_process: true,
port: 4444,
server_path: '', // Leave empty if @nightwatch/selenium-server is installed
command: 'standalone', // Selenium 4 only
cli_args: {
//'webdriver.gecko.driver': '',
//'webdriver.chrome.driver': ''
}
},
webdriver: {
start_process: false,
default_path_prefix: '/wd/hub'
}
},
'selenium.chrome': {
extends: 'selenium_server',
desiredCapabilities: {
browserName: 'chrome',
chromeOptions : {
w3c: true
}
}
},
'selenium.firefox': {
extends: 'selenium_server',
desiredCapabilities: {
browserName: 'firefox',
'moz:firefoxOptions': {
args: [
// '-headless',
// '-verbose'
]
}
}
}
}
};

@ -29,6 +29,7 @@
"installRipGrepMacOXarm64": "rm -rf node_modules/@vscode/ripgrep/bin && npm_config_arch=arm64 node node_modules/@vscode/ripgrep/lib/postinstall.js",
"postinstall": "electron-builder install-app-deps",
"selenium-install-linux": "selenium-standalone install --drivers.chrome.version=116.0.5845.228 --drivers.chrome.baseURL=https://chromedriver.storage.googleapis.com",
"selenium-install-win": "selenium-standalone install --drivers.chrome.version=116.0.5845.228 --drivers.chrome.baseURL=https://chromedriver.storage.googleapis.com",
"selenium-install-mac": "selenium-standalone install --drivers.chromiumedge.version=114.0.1788.0 --drivers.chrome.version=114.0.1788.0 --drivers.chrome.baseURL=https://chromedriver.storage.googleapis.com",
"selenium-linux": "selenium-standalone start --config=./selenium-linux.config.js",
"selenium-mac": "selenium-standalone start --config=./selenium-mac.config.js",

@ -0,0 +1,10 @@
module.exports = {
baseURL: 'https://selenium-release.storage.googleapis.com',
drivers: {
chrome: {
version: '116.0.5845.96-win32',
arch: process.arch,
baseURL: 'https://chromedriver.storage.googleapis.com'
}
}
}

@ -6,6 +6,7 @@ export let isPackaged = false;
export const version = app.getVersion();
const args = process.argv.slice(1)
console.log("args", args)
export const isE2ELocal = args.find(arg => arg.startsWith('--e2e-local'))
export const isE2E = args.find(arg => arg.startsWith('--e2e'))

@ -73,20 +73,31 @@ module.exports = {
}
}
},
windows: {
winlocal: {
desiredCapabilities: {
browserName: 'chrome',
javascriptEnabled: true,
acceptSslCerts: true,
'goog:chromeOptions': {
"binary": "./out/remixconnect-win32-x64/remixconnect.exe",
"binary": "./release/win-unpacked/Remix-Desktop.exe",
"args": [
"--folder=test/contracts",
"--remix-ide-url=http://localhost:8080",
"--e2e"
"--e2e-local",
]
}
}
}
},
win: {
desiredCapabilities: {
browserName: 'chrome',
javascriptEnabled: true,
acceptSslCerts: true,
'goog:chromeOptions': {
"binary": "./release/win-unpacked/Remix-Desktop.exe",
"args": [
"--e2e",
]
}
}
},
}
}

@ -1,195 +1,217 @@
import { NightwatchBrowser } from 'nightwatch'
import {NightwatchBrowser} from 'nightwatch'
const tests = {
before: function (browser: NightwatchBrowser, done: VoidFunction) {
done()
},
open: function (browser: NightwatchBrowser) {
browser.waitForElementVisible('*[data-id="openFolderButton"]', 10000).click('*[data-id="openFolderButton"]')
},
'open xterm linux and create a file': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="tabXTerm"]', 10000)
.click('*[data-id="tabXTerm"]')
.waitForElementVisible('*[data-type="remixUIXT"]', 10000)
.click('*[data-type="remixUIXT"]')
.perform(function () {
const actions = this.actions({async: true})
return actions.sendKeys('echo test > example.txt').sendKeys(this.Keys.ENTER)
})
.waitForElementVisible('*[data-id="treeViewLitreeViewItemexample.txt"]', 10000)
},
'rename that file': function (browser: NightwatchBrowser) {
browser
.perform(function () {
const actions = this.actions({async: true})
return actions.sendKeys('mv example.txt newExample.txt').sendKeys(this.Keys.ENTER)
})
.waitForElementVisible('*[data-id="treeViewLitreeViewItemnewExample.txt"]', 10000)
},
'create a file and delete it': function (browser: NightwatchBrowser) {
browser
.perform(function () {
const actions = this.actions({async: true})
return actions.sendKeys('touch newExample2.txt').sendKeys(this.Keys.ENTER)
})
.waitForElementVisible('*[data-id="treeViewLitreeViewItemnewExample2.txt"]', 10000)
.perform(function () {
const actions = this.actions({async: true})
return actions.sendKeys('rm newExample2.txt').sendKeys(this.Keys.ENTER)
})
.waitForElementNotPresent('*[data-id="treeViewLitreeViewItemnewExample2.txt"]', 10000)
},
'run a git clone command': function (browser: NightwatchBrowser) {
browser
.perform(function () {
const actions = this.actions({async: true})
return actions.sendKeys('git clone https://github.com/ethereum/awesome-remix').sendKeys(this.Keys.ENTER)
})
.waitForElementVisible('*[data-id="treeViewLitreeViewItemawesome-remix"]', 10000)
.click('*[data-id="treeViewLitreeViewItemawesome-remix"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemawesome-remix/README.md"]', 10000)
},
'remove the cloned repo': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-type="remixUIXT"]', 10000)
.click('*[data-type="remixUIXT"]')
.perform(function () {
const actions = this.actions({async: true})
return actions.sendKeys('rm -rf awesome-remix').sendKeys(this.Keys.ENTER)
})
.waitForElementNotPresent('*[data-id="treeViewLitreeViewItemawesome-remix"]', 10000)
},
'list files': function (browser: NightwatchBrowser) {
browser
.perform(function () {
const actions = this.actions({async: true})
return actions.sendKeys('ls').sendKeys(this.Keys.ENTER)
})
.waitForElementVisible({
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath',
})
.getText(
{
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath',
},
function (result) {
console.log('Text content of the element:', result.value)
browser.assert.ok((result.value as string).includes('newExample.txt'))
}
)
},
'switch to a new terminal': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="createTerminalButton"]', 10000)
.click('*[data-id="createTerminalButton"]')
.elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) {
browser.assert.ok((result.value as any).length === 2)
})
.getText(
{
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath',
},
function (result) {
console.log('Text content of the element:', result.value)
browser.assert.ok(!(result.value as string).includes('newExample.txt'))
}
)
},
'switch to a third terminal': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="createTerminalButton"]', 10000)
.click('*[data-id="createTerminalButton"]')
.waitForElementVisible(
{
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath',
},
10000
)
.click({
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath',
})
.elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) {
browser.assert.ok((result.value as any).length === 3)
})
.perform(function () {
const actions = this.actions({async: true})
return actions.sendKeys('echo thirdterminal').sendKeys(this.Keys.ENTER)
})
},
'switch back to the second terminal': function (browser: NightwatchBrowser) {
browser
.elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) {
browser.elementIdClick(Object.values((result.value as any)[1])[0] as any)
})
.getText(
{
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath',
},
function (result) {
console.log('Text content of the element:', result.value)
browser.assert.ok(!(result.value as string).includes('newExample.txt'))
}
)
},
'close the second terminal': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="closeTerminalButton"]', 10000)
.click('*[data-id="closeTerminalButton"]')
.elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) {
browser.assert.ok((result.value as any).length === 2)
})
},
'switch back to the first terminal': function (browser: NightwatchBrowser) {
browser
.elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) {
browser.elementIdClick(Object.values((result.value as any)[0])[0] as any)
})
.getText(
{
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath',
},
function (result) {
console.log('Text content of the element:', result.value)
browser.assert.ok((result.value as string).includes('newExample.txt'))
}
)
},
'switch to the output panel': function (browser: NightwatchBrowser) {
browser.waitForElementVisible('*[data-id="tabOutput"]', 10000).click('*[data-id="tabOutput"]').waitForElementNotPresent('*[data-id="createTerminalButton"]', 10000)
},
'switch back to xterminal': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="tabXTerm"]', 10000)
.click('*[data-id="tabXTerm"]')
.waitForElementVisible('*[data-type="remixUIXT"]', 10000)
.click('*[data-type="remixUIXT"]')
.getText(
{
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath',
},
function (result) {
console.log('Text content of the element:', result.value)
browser.assert.ok((result.value as string).includes('newExample.txt'))
}
)
},
'clear the terminal': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="clearTerminalButton"]', 10000)
.click('*[data-id="clearTerminalButton"]')
.getText(
{
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath',
},
function (result) {
console.log('Text content of the element:', result.value)
browser.assert.ok(!(result.value as string).includes('newExample.txt'))
}
)
},
}
module.exports = {
before: function (browser: NightwatchBrowser, done: VoidFunction) {
done()
},
'opem template': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="openFolderButton"]', 10000)
.click('*[data-id="openFolderButton"]')
},
'open xterm linux and create a file': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="tabXTerm"]', 10000)
.click('*[data-id="tabXTerm"]')
.waitForElementVisible('*[data-type="remixUIXT"]', 10000)
.click('*[data-type="remixUIXT"]')
.perform(function () {
const actions = this.actions({ async: true })
return actions.sendKeys('echo test > example.txt').sendKeys(this.Keys.ENTER)
})
.waitForElementVisible('*[data-id="treeViewLitreeViewItemexample.txt"]', 10000)
},
'rename that file': function (browser: NightwatchBrowser) {
browser
.perform(function () {
const actions = this.actions({ async: true })
return actions.sendKeys('mv example.txt newExample.txt').sendKeys(this.Keys.ENTER)
})
.waitForElementVisible('*[data-id="treeViewLitreeViewItemnewExample.txt"]', 10000)
},
'create a file and delete it': function (browser: NightwatchBrowser) {
browser
.perform(function () {
const actions = this.actions({ async: true })
return actions.sendKeys('touch newExample2.txt').sendKeys(this.Keys.ENTER)
})
.waitForElementVisible('*[data-id="treeViewLitreeViewItemnewExample2.txt"]', 10000)
.perform(function () {
const actions = this.actions({ async: true })
return actions.sendKeys('rm newExample2.txt').sendKeys(this.Keys.ENTER)
})
.waitForElementNotPresent('*[data-id="treeViewLitreeViewItemnewExample2.txt"]', 10000)
},
'run a git clone command': function (browser: NightwatchBrowser) {
browser
.perform(function () {
const actions = this.actions({ async: true })
return actions.sendKeys('git clone https://github.com/ethereum/awesome-remix').sendKeys(this.Keys.ENTER)
}
)
.waitForElementVisible('*[data-id="treeViewLitreeViewItemawesome-remix"]', 10000)
.click('*[data-id="treeViewLitreeViewItemawesome-remix"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemawesome-remix/README.md"]', 10000)
},
'remove the cloned repo': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-type="remixUIXT"]', 10000)
.click('*[data-type="remixUIXT"]')
.perform(function () {
const actions = this.actions({ async: true })
return actions.sendKeys('rm -rf awesome-remix').sendKeys(this.Keys.ENTER)
}
)
.waitForElementNotPresent('*[data-id="treeViewLitreeViewItemawesome-remix"]', 10000)
},
'list files': function (browser: NightwatchBrowser) {
browser
.perform(function () {
const actions = this.actions({ async: true })
return actions.sendKeys('ls').sendKeys(this.Keys.ENTER)
})
.waitForElementVisible({
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath'
})
.getText({
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath'
}, function (result) {
console.log('Text content of the element:', result.value);
browser.assert.ok((result.value as string).includes('newExample.txt'))
})
},
'switch to a new terminal': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="createTerminalButton"]', 10000)
.click('*[data-id="createTerminalButton"]')
.elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) {
browser.assert.ok((result.value as any).length === 2)
})
.getText({
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath'
}, function (result) {
console.log('Text content of the element:', result.value);
browser.assert.ok(!(result.value as string).includes('newExample.txt'))
})
},
'switch to a third terminal': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="createTerminalButton"]', 10000)
.click('*[data-id="createTerminalButton"]')
.waitForElementVisible({
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath'
}, 10000)
.click({
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath'
})
.elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) {
browser.assert.ok((result.value as any).length === 3)
})
.perform(function () {
const actions = this.actions({ async: true })
return actions.sendKeys('echo thirdterminal').sendKeys(this.Keys.ENTER)
})
},
'switch back to the second terminal': function (browser: NightwatchBrowser) {
browser
.elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) {
browser.elementIdClick(((Object.values((result.value as any)[1]))[0] as any))
})
.getText({
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath'
}, function (result) {
console.log('Text content of the element:', result.value);
browser.assert.ok(!(result.value as string).includes('newExample.txt'))
})
},
'close the second terminal': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="closeTerminalButton"]', 10000)
.click('*[data-id="closeTerminalButton"]')
.elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) {
browser.assert.ok((result.value as any).length === 2)
})
},
'switch back to the first terminal': function (browser: NightwatchBrowser) {
browser
.elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) {
browser.elementIdClick(((Object.values((result.value as any)[0]))[0] as any))
})
.getText({
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath'
}, function (result) {
console.log('Text content of the element:', result.value);
browser.assert.ok((result.value as string).includes('newExample.txt'))
})
},
'switch to the output panel': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="tabOutput"]', 10000)
.click('*[data-id="tabOutput"]')
.waitForElementNotPresent('*[data-id="createTerminalButton"]', 10000)
},
'switch back to xterminal': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="tabXTerm"]', 10000)
.click('*[data-id="tabXTerm"]')
.waitForElementVisible('*[data-type="remixUIXT"]', 10000)
.click('*[data-type="remixUIXT"]')
.getText({
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath'
}, function (result) {
console.log('Text content of the element:', result.value);
browser.assert.ok((result.value as string).includes('newExample.txt'))
})
},
'clear the terminal': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="clearTerminalButton"]', 10000)
.click('*[data-id="clearTerminalButton"]')
.getText({
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath'
}, function (result) {
console.log('Text content of the element:', result.value);
browser.assert.ok(!(result.value as string).includes('newExample.txt'))
})
}
...process.platform.startsWith('win')?{}:tests
}

@ -0,0 +1,243 @@
import {NightwatchBrowser} from 'nightwatch'
const tests = {
before: function (browser: NightwatchBrowser, done: VoidFunction) {
done()
},
open: function (browser: NightwatchBrowser) {
browser.waitForElementVisible('*[data-id="openFolderButton"]', 10000).click('*[data-id="openFolderButton"]')
},
'open xterm linux and create a file': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="tabXTerm"]', 10000)
.click('*[data-id="tabXTerm"]')
.waitForElementVisible('*[data-id="select_shell"]')
.click('*[data-id="select_shell"]')
.waitForElementVisible('*[data-id="select_powershell.exe"]')
.click('*[data-id="select_powershell.exe"]')
.pause(3000)
.waitForElementVisible("[data-active='1'][data-type='remixUIXT']", 10000)
.click("[data-active='1'][data-type='remixUIXT']")
.pause(1000)
.perform(function () {
const actions = this.actions({async: true})
return actions.sendKeys('"test" | Out-File -FilePath example.txt').sendKeys(this.Keys.ENTER)
})
.waitForElementVisible('*[data-id="treeViewLitreeViewItemexample.txt"]', 10000)
},
'rename that file': function (browser: NightwatchBrowser) {
browser
.perform(function () {
const actions = this.actions({async: true})
return actions.sendKeys('Move-Item -Path example.txt -Destination newExample.txt').sendKeys(this.Keys.ENTER)
})
.waitForElementVisible('*[data-id="treeViewLitreeViewItemnewExample.txt"]', 10000)
},
'create a file and delete it': function (browser: NightwatchBrowser) {
browser
.perform(function () {
const actions = this.actions({async: true})
return actions.sendKeys('touch newExample2.txt').sendKeys(this.Keys.ENTER)
})
.waitForElementVisible('*[data-id="treeViewLitreeViewItemnewExample2.txt"]', 10000)
.perform(function () {
const actions = this.actions({async: true})
return actions.sendKeys('Remove-Item -Path newExample2.txt').sendKeys(this.Keys.ENTER)
})
.waitForElementNotPresent('*[data-id="treeViewLitreeViewItemnewExample2.txt"]', 10000)
},
'run a git clone command': function (browser: NightwatchBrowser) {
browser
.perform(function () {
const actions = this.actions({async: true})
return actions.sendKeys('git clone https://github.com/ethereum/awesome-remix').sendKeys(this.Keys.ENTER)
})
.waitForElementVisible('*[data-id="treeViewLitreeViewItemawesome-remix"]', 10000)
.click('*[data-id="treeViewLitreeViewItemawesome-remix"]')
.waitForElementVisible('*[data-id="treeViewLitreeViewItemawesome-remix/README.md"]', 10000)
},
'remove the cloned repo': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible("[data-active='1'][data-type='remixUIXT']", 10000)
.click("[data-active='1'][data-type='remixUIXT']")
.perform(function () {
const actions = this.actions({async: true})
return actions.sendKeys('Remove-Item -Path awesome-remix -Recurse -Force').sendKeys(this.Keys.ENTER)
})
.waitForElementNotPresent('*[data-id="treeViewLitreeViewItemawesome-remix"]', 10000)
},
'list files': function (browser: NightwatchBrowser) {
browser
.perform(function () {
const actions = this.actions({async: true})
return actions.sendKeys('ls').sendKeys(this.Keys.ENTER)
})
.waitForElementVisible({
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath',
})
.getText(
{
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath',
},
function (result) {
console.log('Text content of the element:', result.value)
browser.assert.ok((result.value as string).includes('newExample.txt'))
}
)
},
'switch to a new terminal': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="select_shell"]')
.click('*[data-id="select_shell"]')
.waitForElementVisible('*[data-id="select_powershell.exe"]')
.click('*[data-id="select_powershell.exe"]')
.pause(3000)
.elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) {
console.log(result)
browser.assert.ok((result.value as any).length === 3)
})
.getText(
{
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath',
},
function (result) {
console.log('Text content of the element:', result.value)
browser.assert.ok(!(result.value as string).includes('newExample.txt'))
}
)
},
'switch to a third terminal': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="select_shell"]')
.click('*[data-id="select_shell"]')
.waitForElementVisible('*[data-id="select_powershell.exe"]')
.click('*[data-id="select_powershell.exe"]')
.pause(3000)
.waitForElementVisible(
{
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath',
},
10000
)
.click({
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath',
})
.elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) {
browser.assert.ok((result.value as any).length === 4)
})
.perform(function () {
const actions = this.actions({async: true})
return actions.sendKeys('echo thirdterminal').sendKeys(this.Keys.ENTER)
})
},
'switch back to the second terminal': function (browser: NightwatchBrowser) {
browser
.elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) {
browser.elementIdClick(Object.values((result.value as any)[2])[0] as any)
})
.getText(
{
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath',
},
function (result) {
console.log('Text content of the element:', result.value)
browser.assert.ok(!(result.value as string).includes('newExample.txt'))
}
)
},
'close the second terminal': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="closeTerminalButton"]', 10000)
.click('*[data-id="closeTerminalButton"]')
.pause(1000)
.elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) {
browser.assert.ok((result.value as any).length === 3)
})
},
'switch back to the first terminal': function (browser: NightwatchBrowser) {
browser
.elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) {
browser.elementIdClick(Object.values((result.value as any)[1])[0] as any)
})
.getText(
{
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath',
},
function (result) {
console.log('Text content of the element:', result.value)
browser.assert.ok((result.value as string).includes('newExample.txt'))
}
)
},
'switch to the output panel': function (browser: NightwatchBrowser) {
browser.waitForElementVisible('*[data-id="tabOutput"]', 10000).click('*[data-id="tabOutput"]').waitForElementNotPresent('*[data-id="createTerminalButton"]', 10000)
},
'switch back to xterminal': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="tabXTerm"]', 10000)
.click('*[data-id="tabXTerm"]')
.waitForElementVisible("[data-active='1'][data-type='remixUIXT']", 10000)
.click("[data-active='1'][data-type='remixUIXT']")
.getText(
{
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath',
},
function (result) {
console.log('Text content of the element:', result.value)
browser.assert.ok((result.value as string).includes('newExample.txt'))
}
)
},
'clear the terminal': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="clearTerminalButton"]', 10000)
.click('*[data-id="clearTerminalButton"]')
.getText(
{
selector: "//*[@data-type='remixUIXT' and @data-active='1']",
timeout: 10000,
locateStrategy: 'xpath',
},
function (result) {
console.log('Text content of the element:', result.value)
browser.assert.ok(!(result.value as string).includes('newExample.txt'))
}
)
},
'close all terminals': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="closeTerminalButton"]', 10000)
.click('*[data-id="closeTerminalButton"]')
.pause(3000)
.click('*[data-id="closeTerminalButton"]')
.pause(3000)
.click('*[data-id="closeTerminalButton"]')
.pause(3000)
.elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) {
browser.assert.ok((result.value as any).length === 0)
}).end()
},
after: function (browser: NightwatchBrowser) {
browser.end()
},
}
module.exports = {
...process.platform.startsWith('win')?tests:{}
}

@ -35,10 +35,10 @@ export const RemixUIXtermMenu = (props: RemixUiTerminalProps) => {
<div className=''>
<CustomTooltip tooltipText={<FormattedMessage id='xterm.shells' defaultMessage='Shells' />}>
<Dropdown as={ButtonGroup}>
<Dropdown.Toggle split variant="" id="dropdown-split-basic" />
<Dropdown.Menu className='custom-dropdown-items remixui_menuwidth'>
<Dropdown.Toggle data-id='select_shell' split variant="" id="dropdown-split-basic" />
<Dropdown.Menu className='custom-dropdown-items remixui_menuwidth'>
{xtermState.shells.map((shell, index) => {
return (<Dropdown.Item key={index} onClick={async () => await onCreateTerminal(shell)}>{shell}</Dropdown.Item>)
return (<Dropdown.Item data-id={`select_${shell}`} key={index} onClick={async () => await onCreateTerminal(shell)}>{shell}</Dropdown.Item>)
})}
</Dropdown.Menu>
</Dropdown>

Loading…
Cancel
Save