fix modal/toaster (queue)

pull/1999/head
yann300 3 years ago
parent cdb460ea09
commit e74843dcc9
  1. 2
      apps/remix-ide-e2e/src/local-plugin/src/app/app.tsx
  2. 4
      apps/remix-ide-e2e/src/tests/ballot.test.ts
  3. 4
      apps/remix-ide-e2e/src/tests/ballot_0_4_11.test.ts
  4. 72
      apps/remix-ide-e2e/src/tests/plugin_api.ts
  5. 2
      apps/remix-ide-e2e/src/tests/terminal.test.ts
  6. 1
      apps/remix-ide/src/remixEngine.js
  7. 97
      libs/remix-ui/app/src/lib/remix-app/reducer/modals.ts

@ -33,7 +33,7 @@ function App () {
useEffect(() => {
client.onload(async () => {
const customProfiles = ['menuicons', 'tabs', 'solidityUnitTesting', 'hardhat-provider']
const customProfiles = ['menuicons', 'tabs', 'solidityUnitTesting', 'hardhat-provider', 'notification']
client.testCommand = async (data: any) => {
console.log(data)

@ -84,9 +84,9 @@ module.exports = {
.openFile('Untitled.sol')
.clickLaunchIcon('udapp')
.click('*[data-id="settingsWeb3Mode"]')
.waitForElementPresent('[data-id="udappNotify-modal-footer-ok-react"]')
.waitForElementPresent('[data-id="envNotification-modal-footer-ok-react"]')
.execute(function () {
const modal = document.querySelector('[data-id="udappNotify-modal-footer-ok-react"]') as any
const modal = document.querySelector('[data-id="envNotification-modal-footer-ok-react"]') as any
modal.click()
})

@ -79,9 +79,9 @@ module.exports = {
.openFile('Untitled.sol')
.clickLaunchIcon('udapp')
.click('*[data-id="settingsWeb3Mode"]')
.waitForElementPresent('[data-id="udappNotify-modal-footer-ok-react"]')
.waitForElementPresent('[data-id="envNotification-modal-footer-ok-react"]')
.execute(function () {
const modal = document.querySelector('[data-id="udappNotify-modal-footer-ok-react"]') as any
const modal = document.querySelector('[data-id="envNotification-modal-footer-ok-react"]') as any
modal.click()
})

@ -64,12 +64,16 @@ const clearPayLoad = async (browser: NightwatchBrowser) => {
})
}
const clickButton = async (browser: NightwatchBrowser, buttonText: string) => {
const clickButton = async (browser: NightwatchBrowser, buttonText: string, waitResult: boolean = true) => {
return new Promise((resolve) => {
browser.useXpath().waitForElementVisible(`//*[@data-id='${buttonText}']`).pause(100)
.click(`//*[@data-id='${buttonText}']`, async () => {
await checkForAcceptAndRemember(browser)
browser.waitForElementContainsText('//*[@id="callStatus"]', 'stop').perform(() => resolve(true))
if (waitResult) {
browser.waitForElementContainsText('//*[@id="callStatus"]', 'stop').perform(() => resolve(true))
} else {
resolve(true)
}
})
})
}
@ -103,7 +107,7 @@ const checkForAcceptAndRemember = async function (browser: NightwatchBrowser) {
* @return {Promise}
*/
const clickAndCheckLog = async (browser: NightwatchBrowser, buttonText: string, methodResult: any, eventResult: any, payload: any) => {
const clickAndCheckLog = async (browser: NightwatchBrowser, buttonText: string, methodResult: any, eventResult: any, payload: any, waitResult: boolean = true) => {
if (payload) {
await setPayload(browser, payload)
} else {
@ -112,10 +116,14 @@ const clickAndCheckLog = async (browser: NightwatchBrowser, buttonText: string,
if (methodResult && typeof methodResult !== 'string') { methodResult = JSON.stringify(methodResult) }
if (eventResult && typeof eventResult !== 'string') { eventResult = JSON.stringify(eventResult) }
if (buttonText) {
await clickButton(browser, buttonText)
await clickButton(browser, buttonText, waitResult)
}
if (methodResult) {
await debugValues(browser, 'methods', methodResult)
}
if (eventResult) {
await debugValues(browser, 'events', eventResult)
}
await debugValues(browser, 'methods', methodResult)
await debugValues(browser, 'events', eventResult)
}
const assertPluginIsActive = function (browser: NightwatchBrowser, id: string, shouldBeVisible: boolean) {
@ -364,5 +372,57 @@ module.exports = {
const result = '{"jsonrpc":"2.0","result":true,"id":9999}'
await clickAndCheckLog(browser, 'hardhat-provider:sendAsync', result, null, request)
})
},
// MODAL
'Should open 2 alert in a row and trigger 2 toaster in between #group9': function (browser: NightwatchBrowser) {
browser
.frameParent()
.useCss()
.addFile('test_modal.js', { content: testModalToasterApi })
.executeScript('remix.execute(\'test_modal.js\')')
.clickLaunchIcon('localPlugin')
.useXpath()
// @ts-ignore
.frame(0)
.perform(async () => {
await clickAndCheckLog(browser, 'notification:toast', null, null, 'message toast from local plugin', false) // create a toast on behalf of the localplugin
await clickAndCheckLog(browser, 'notification:alert', null, null, { message: 'message from local plugin', id: 'test_id_1_local_plugin' }, false) // create an alert on behalf of the localplugin
})
.frameParent()
.useCss()
// check the local plugin notifications
.waitForElementVisible('*[data-id="test_id_1_local_pluginModalDialogModalBody-react"]')
.assert.containsText('*[data-id="test_id_1_local_pluginModalDialogModalBody-react"]', 'message from local plugin')
.modalFooterOKClick('test_id_1_local_plugin')
// check the script runner notifications
.waitForElementVisible('*[data-id="test_id_1_ModalDialogModalBody-react"]')
.assert.containsText('*[data-id="test_id_1_ModalDialogModalBody-react"]', 'message 1')
.modalFooterOKClick('test_id_1_')
.waitForElementVisible('*[data-id="test_id_2_ModalDialogModalBody-react"]')
.assert.containsText('*[data-id="test_id_2_ModalDialogModalBody-react"]', 'message 2')
.modalFooterOKClick('test_id_2_')
// check the toasters
.waitForElementVisible('*[data-shared="tooltipPopup"]')
.waitForElementContainsText('*[data-shared="tooltipPopup"]', 'message toast from local plugin')
.waitForElementContainsText('*[data-shared="tooltipPopup"]', 'I am a toast')
.waitForElementContainsText('*[data-shared="tooltipPopup"]', 'I am a re-toast')
}
}
const testModalToasterApi = `
// Right click on the script name and hit "Run" to execute
(async () => {
try {
setTimeout(() => {
console.log('test .. ')
remix.call('notification', 'alert', { message: 'message 1', id: 'test_id_1_' })
remix.call('notification', 'toast', 'I am a toast')
remix.call('notification', 'toast', 'I am a re-toast')
remix.call('notification', 'alert', { message: 'message 2', id: 'test_id_2_' })
}, 500)
} catch (e) {
console.log(e.message)
}
})() `

@ -51,7 +51,7 @@ module.exports = {
.click('*[data-id="terminalClearConsole"]') // clear the terminal
.clickLaunchIcon('udapp')
.click('*[data-id="settingsWeb3Mode"]')
.modalFooterOKClick('udappNotify')
.modalFooterOKClick('envNotification')
.executeScript('web3.eth.getAccounts()')
.waitForElementContainsText('*[data-id="terminalJournal"]', '["', 60000) // we check if an array is present, don't need to check for the content
.waitForElementContainsText('*[data-id="terminalJournal"]', '"]', 60000)

@ -14,6 +14,7 @@ export class RemixEngine extends Engine {
if (name === 'slither') return { queueTimeout: 60000 * 4 } // Requires when a solc version is installed
if (name === 'hardhat') return { queueTimeout: 60000 * 4 }
if (name === 'localPlugin') return { queueTimeout: 60000 * 4 }
if (name === 'notification') return { queueTimeout: 60000 * 4 }
return { queueTimeout: 10000 }
}

@ -5,49 +5,68 @@ import { AppModal, ModalState } from '../interface'
export const modalReducer = (state: ModalState = ModalInitialState, action: ModalAction) => {
switch (action.type) {
case modalActionTypes.setModal: {
let modalList:AppModal[] = state.modals
modalList.push(action.payload)
if (state.modals.length === 1 && state.focusModal.hide === true) { // if it's the first one show it
const focusModal: AppModal = {
id: modalList[0].id,
hide: false,
title: modalList[0].title,
message: modalList[0].message,
okLabel: modalList[0].okLabel,
okFn: modalList[0].okFn,
cancelLabel: modalList[0].cancelLabel,
cancelFn: modalList[0].cancelFn,
modalType: modalList[0].modalType,
defaultValue: modalList[0].defaultValue,
hideFn: modalList[0].hideFn,
resolve: modalList[0].resolve
}
const focusModal: AppModal = {
id: action.payload.id || Date.now().toString(),
hide: false,
title: action.payload.title,
message: action.payload.message,
okLabel: action.payload.okLabel,
okFn: action.payload.okFn,
cancelLabel: action.payload.cancelLabel,
cancelFn: action.payload.cancelFn,
modalType: action.payload.modalType,
defaultValue: action.payload.defaultValue,
hideFn: action.payload.hideFn,
resolve: action.payload.resolve
}
const modalList: AppModal[] = state.modals.slice()
modalList.push(focusModal)
modalList = modalList.slice()
modalList.shift()
return { ...state, modals: modalList, focusModal: focusModal }
if (modalList.length === 1) {
return { ...state, modals: modalList, focusModal }
} else {
return { ...state, modals: modalList }
}
return { ...state, modals: modalList }
}
case modalActionTypes.handleHideModal:
if (state.focusModal.hideFn) {
state.focusModal.hideFn()
} else if (state.focusModal.resolve) {
state.focusModal.resolve(undefined)
case modalActionTypes.handleHideModal: {
setTimeout(() => {
if (state.focusModal.hideFn) {
state.focusModal.hideFn()
}
if (state.focusModal.resolve) {
state.focusModal.resolve(undefined)
}
}, 250)
const modalList: AppModal[] = state.modals.slice()
modalList.shift() // remove the current modal from the list
if (modalList.length) {
const focusModal = modalList[0] // extract the next modal from the list
return { ...state, modals: modalList, focusModal }
} else {
state.focusModal = { ...state.focusModal, hide: true, message: null }
return { ...state, modals: [] }
}
state.focusModal = { ...state.focusModal, hide: true, message: null }
return { ...state }
case modalActionTypes.setToast:
state.toasters.push(action.payload)
if (state.toasters.length > 0) {
const focus = state.toasters[0]
state.toasters.shift()
return { ...state, focusToaster: focus }
}
case modalActionTypes.setToast: {
const toasterList = state.toasters.slice()
const message = action.payload
toasterList.push(message)
if (toasterList.length === 1) {
return { ...state, toasters: toasterList, focusToaster: action.payload }
} else {
return { ...state, toasters: toasterList }
}
return { ...state }
case modalActionTypes.handleToaster:
return { ...state, focusToaster: '' }
}
case modalActionTypes.handleToaster: {
const toasterList = state.toasters.slice()
toasterList.shift()
if (toasterList.length) {
const toaster = toasterList[0]
return { ...state, toasters: toasterList, focusToaster: toaster }
} else {
return { ...state, toasters: [] }
}
}
}
}

Loading…
Cancel
Save