Skip to content

Commit e74843d

Browse files
committed
fix modal/toaster (queue)
1 parent cdb460e commit e74843d

File tree

7 files changed

+131
-51
lines changed

7 files changed

+131
-51
lines changed

apps/remix-ide-e2e/src/local-plugin/src/app/app.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ function App () {
3333

3434
useEffect(() => {
3535
client.onload(async () => {
36-
const customProfiles = ['menuicons', 'tabs', 'solidityUnitTesting', 'hardhat-provider']
36+
const customProfiles = ['menuicons', 'tabs', 'solidityUnitTesting', 'hardhat-provider', 'notification']
3737

3838
client.testCommand = async (data: any) => {
3939
console.log(data)

apps/remix-ide-e2e/src/tests/ballot.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ module.exports = {
8484
.openFile('Untitled.sol')
8585
.clickLaunchIcon('udapp')
8686
.click('*[data-id="settingsWeb3Mode"]')
87-
.waitForElementPresent('[data-id="udappNotify-modal-footer-ok-react"]')
87+
.waitForElementPresent('[data-id="envNotification-modal-footer-ok-react"]')
8888
.execute(function () {
89-
const modal = document.querySelector('[data-id="udappNotify-modal-footer-ok-react"]') as any
89+
const modal = document.querySelector('[data-id="envNotification-modal-footer-ok-react"]') as any
9090

9191
modal.click()
9292
})

apps/remix-ide-e2e/src/tests/ballot_0_4_11.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@ module.exports = {
7979
.openFile('Untitled.sol')
8080
.clickLaunchIcon('udapp')
8181
.click('*[data-id="settingsWeb3Mode"]')
82-
.waitForElementPresent('[data-id="udappNotify-modal-footer-ok-react"]')
82+
.waitForElementPresent('[data-id="envNotification-modal-footer-ok-react"]')
8383
.execute(function () {
84-
const modal = document.querySelector('[data-id="udappNotify-modal-footer-ok-react"]') as any
84+
const modal = document.querySelector('[data-id="envNotification-modal-footer-ok-react"]') as any
8585

8686
modal.click()
8787
})

apps/remix-ide-e2e/src/tests/plugin_api.ts

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,16 @@ const clearPayLoad = async (browser: NightwatchBrowser) => {
6464
})
6565
}
6666

67-
const clickButton = async (browser: NightwatchBrowser, buttonText: string) => {
67+
const clickButton = async (browser: NightwatchBrowser, buttonText: string, waitResult: boolean = true) => {
6868
return new Promise((resolve) => {
6969
browser.useXpath().waitForElementVisible(`//*[@data-id='${buttonText}']`).pause(100)
7070
.click(`//*[@data-id='${buttonText}']`, async () => {
7171
await checkForAcceptAndRemember(browser)
72-
browser.waitForElementContainsText('//*[@id="callStatus"]', 'stop').perform(() => resolve(true))
72+
if (waitResult) {
73+
browser.waitForElementContainsText('//*[@id="callStatus"]', 'stop').perform(() => resolve(true))
74+
} else {
75+
resolve(true)
76+
}
7377
})
7478
})
7579
}
@@ -103,7 +107,7 @@ const checkForAcceptAndRemember = async function (browser: NightwatchBrowser) {
103107
* @return {Promise}
104108
*/
105109

106-
const clickAndCheckLog = async (browser: NightwatchBrowser, buttonText: string, methodResult: any, eventResult: any, payload: any) => {
110+
const clickAndCheckLog = async (browser: NightwatchBrowser, buttonText: string, methodResult: any, eventResult: any, payload: any, waitResult: boolean = true) => {
107111
if (payload) {
108112
await setPayload(browser, payload)
109113
} else {
@@ -112,10 +116,14 @@ const clickAndCheckLog = async (browser: NightwatchBrowser, buttonText: string,
112116
if (methodResult && typeof methodResult !== 'string') { methodResult = JSON.stringify(methodResult) }
113117
if (eventResult && typeof eventResult !== 'string') { eventResult = JSON.stringify(eventResult) }
114118
if (buttonText) {
115-
await clickButton(browser, buttonText)
119+
await clickButton(browser, buttonText, waitResult)
120+
}
121+
if (methodResult) {
122+
await debugValues(browser, 'methods', methodResult)
123+
}
124+
if (eventResult) {
125+
await debugValues(browser, 'events', eventResult)
116126
}
117-
await debugValues(browser, 'methods', methodResult)
118-
await debugValues(browser, 'events', eventResult)
119127
}
120128

121129
const assertPluginIsActive = function (browser: NightwatchBrowser, id: string, shouldBeVisible: boolean) {
@@ -364,5 +372,57 @@ module.exports = {
364372
const result = '{"jsonrpc":"2.0","result":true,"id":9999}'
365373
await clickAndCheckLog(browser, 'hardhat-provider:sendAsync', result, null, request)
366374
})
375+
},
376+
377+
// MODAL
378+
379+
'Should open 2 alert in a row and trigger 2 toaster in between #group9': function (browser: NightwatchBrowser) {
380+
browser
381+
.frameParent()
382+
.useCss()
383+
.addFile('test_modal.js', { content: testModalToasterApi })
384+
.executeScript('remix.execute(\'test_modal.js\')')
385+
.clickLaunchIcon('localPlugin')
386+
.useXpath()
387+
// @ts-ignore
388+
.frame(0)
389+
.perform(async () => {
390+
await clickAndCheckLog(browser, 'notification:toast', null, null, 'message toast from local plugin', false) // create a toast on behalf of the localplugin
391+
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
392+
})
393+
.frameParent()
394+
.useCss()
395+
// check the local plugin notifications
396+
.waitForElementVisible('*[data-id="test_id_1_local_pluginModalDialogModalBody-react"]')
397+
.assert.containsText('*[data-id="test_id_1_local_pluginModalDialogModalBody-react"]', 'message from local plugin')
398+
.modalFooterOKClick('test_id_1_local_plugin')
399+
// check the script runner notifications
400+
.waitForElementVisible('*[data-id="test_id_1_ModalDialogModalBody-react"]')
401+
.assert.containsText('*[data-id="test_id_1_ModalDialogModalBody-react"]', 'message 1')
402+
.modalFooterOKClick('test_id_1_')
403+
.waitForElementVisible('*[data-id="test_id_2_ModalDialogModalBody-react"]')
404+
.assert.containsText('*[data-id="test_id_2_ModalDialogModalBody-react"]', 'message 2')
405+
.modalFooterOKClick('test_id_2_')
406+
// check the toasters
407+
.waitForElementVisible('*[data-shared="tooltipPopup"]')
408+
.waitForElementContainsText('*[data-shared="tooltipPopup"]', 'message toast from local plugin')
409+
.waitForElementContainsText('*[data-shared="tooltipPopup"]', 'I am a toast')
410+
.waitForElementContainsText('*[data-shared="tooltipPopup"]', 'I am a re-toast')
367411
}
368412
}
413+
414+
const testModalToasterApi = `
415+
// Right click on the script name and hit "Run" to execute
416+
(async () => {
417+
try {
418+
setTimeout(() => {
419+
console.log('test .. ')
420+
remix.call('notification', 'alert', { message: 'message 1', id: 'test_id_1_' })
421+
remix.call('notification', 'toast', 'I am a toast')
422+
remix.call('notification', 'toast', 'I am a re-toast')
423+
remix.call('notification', 'alert', { message: 'message 2', id: 'test_id_2_' })
424+
}, 500)
425+
} catch (e) {
426+
console.log(e.message)
427+
}
428+
})() `

apps/remix-ide-e2e/src/tests/terminal.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ module.exports = {
5151
.click('*[data-id="terminalClearConsole"]') // clear the terminal
5252
.clickLaunchIcon('udapp')
5353
.click('*[data-id="settingsWeb3Mode"]')
54-
.modalFooterOKClick('udappNotify')
54+
.modalFooterOKClick('envNotification')
5555
.executeScript('web3.eth.getAccounts()')
5656
.waitForElementContainsText('*[data-id="terminalJournal"]', '["', 60000) // we check if an array is present, don't need to check for the content
5757
.waitForElementContainsText('*[data-id="terminalJournal"]', '"]', 60000)

apps/remix-ide/src/remixEngine.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export class RemixEngine extends Engine {
1414
if (name === 'slither') return { queueTimeout: 60000 * 4 } // Requires when a solc version is installed
1515
if (name === 'hardhat') return { queueTimeout: 60000 * 4 }
1616
if (name === 'localPlugin') return { queueTimeout: 60000 * 4 }
17+
if (name === 'notification') return { queueTimeout: 60000 * 4 }
1718
return { queueTimeout: 10000 }
1819
}
1920

libs/remix-ui/app/src/lib/remix-app/reducer/modals.ts

Lines changed: 58 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,49 +5,68 @@ import { AppModal, ModalState } from '../interface'
55
export const modalReducer = (state: ModalState = ModalInitialState, action: ModalAction) => {
66
switch (action.type) {
77
case modalActionTypes.setModal: {
8-
let modalList:AppModal[] = state.modals
9-
modalList.push(action.payload)
10-
if (state.modals.length === 1 && state.focusModal.hide === true) { // if it's the first one show it
11-
const focusModal: AppModal = {
12-
id: modalList[0].id,
13-
hide: false,
14-
title: modalList[0].title,
15-
message: modalList[0].message,
16-
okLabel: modalList[0].okLabel,
17-
okFn: modalList[0].okFn,
18-
cancelLabel: modalList[0].cancelLabel,
19-
cancelFn: modalList[0].cancelFn,
20-
modalType: modalList[0].modalType,
21-
defaultValue: modalList[0].defaultValue,
22-
hideFn: modalList[0].hideFn,
23-
resolve: modalList[0].resolve
24-
}
8+
const focusModal: AppModal = {
9+
id: action.payload.id || Date.now().toString(),
10+
hide: false,
11+
title: action.payload.title,
12+
message: action.payload.message,
13+
okLabel: action.payload.okLabel,
14+
okFn: action.payload.okFn,
15+
cancelLabel: action.payload.cancelLabel,
16+
cancelFn: action.payload.cancelFn,
17+
modalType: action.payload.modalType,
18+
defaultValue: action.payload.defaultValue,
19+
hideFn: action.payload.hideFn,
20+
resolve: action.payload.resolve
21+
}
22+
23+
const modalList: AppModal[] = state.modals.slice()
24+
modalList.push(focusModal)
2525

26-
modalList = modalList.slice()
27-
modalList.shift()
28-
return { ...state, modals: modalList, focusModal: focusModal }
26+
if (modalList.length === 1) {
27+
return { ...state, modals: modalList, focusModal }
28+
} else {
29+
return { ...state, modals: modalList }
2930
}
30-
return { ...state, modals: modalList }
3131
}
32-
case modalActionTypes.handleHideModal:
33-
if (state.focusModal.hideFn) {
34-
state.focusModal.hideFn()
35-
} else if (state.focusModal.resolve) {
36-
state.focusModal.resolve(undefined)
32+
case modalActionTypes.handleHideModal: {
33+
setTimeout(() => {
34+
if (state.focusModal.hideFn) {
35+
state.focusModal.hideFn()
36+
}
37+
if (state.focusModal.resolve) {
38+
state.focusModal.resolve(undefined)
39+
}
40+
}, 250)
41+
const modalList: AppModal[] = state.modals.slice()
42+
modalList.shift() // remove the current modal from the list
43+
if (modalList.length) {
44+
const focusModal = modalList[0] // extract the next modal from the list
45+
return { ...state, modals: modalList, focusModal }
46+
} else {
47+
state.focusModal = { ...state.focusModal, hide: true, message: null }
48+
return { ...state, modals: [] }
3749
}
38-
state.focusModal = { ...state.focusModal, hide: true, message: null }
39-
return { ...state }
40-
41-
case modalActionTypes.setToast:
42-
state.toasters.push(action.payload)
43-
if (state.toasters.length > 0) {
44-
const focus = state.toasters[0]
45-
state.toasters.shift()
46-
return { ...state, focusToaster: focus }
50+
}
51+
case modalActionTypes.setToast: {
52+
const toasterList = state.toasters.slice()
53+
const message = action.payload
54+
toasterList.push(message)
55+
if (toasterList.length === 1) {
56+
return { ...state, toasters: toasterList, focusToaster: action.payload }
57+
} else {
58+
return { ...state, toasters: toasterList }
4759
}
48-
return { ...state }
49-
50-
case modalActionTypes.handleToaster:
51-
return { ...state, focusToaster: '' }
60+
}
61+
case modalActionTypes.handleToaster: {
62+
const toasterList = state.toasters.slice()
63+
toasterList.shift()
64+
if (toasterList.length) {
65+
const toaster = toasterList[0]
66+
return { ...state, toasters: toasterList, focusToaster: toaster }
67+
} else {
68+
return { ...state, toasters: [] }
69+
}
70+
}
5271
}
5372
}

0 commit comments

Comments
 (0)