Skip to content

Commit 6565432

Browse files
committed
fix tests
1 parent 1ef79c6 commit 6565432

File tree

4 files changed

+150
-64
lines changed

4 files changed

+150
-64
lines changed

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

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,20 @@ const templatesToCheck = [
3535
{
3636
value: "ozerc20",
3737
displayName: "ERC20",
38-
checkSelectors: ['*[data-id="treeViewLitreeViewItemcontracts/MyToken.sol"]']
38+
checkSelectors: ['*[data-id="treeViewLitreeViewItemcontracts/MyToken.sol"]'],
39+
clickOk: true
3940
},
4041
{
4142
value: "ozerc721",
4243
displayName: "ERC721",
43-
checkSelectors: ['*[data-id="treeViewLitreeViewItemcontracts/MyToken.sol"]']
44+
checkSelectors: ['*[data-id="treeViewLitreeViewItemcontracts/MyToken.sol"]'],
45+
clickOk: true
4446
},
4547
{
4648
value: "ozerc1155",
4749
displayName: "ERC1155",
48-
checkSelectors: ['*[data-id="treeViewLitreeViewItemcontracts/MyToken.sol"]']
50+
checkSelectors: ['*[data-id="treeViewLitreeViewItemcontracts/MyToken.sol"]'],
51+
clickOk: true
4952
},
5053
{
5154
value: "zeroxErc20",
@@ -119,6 +122,14 @@ const templatesToCheck = [
119122
}
120123
]
121124

125+
function setTemplateOptions(browser: NightwatchBrowser, opts: { [key: string]: any }) {
126+
if (opts.mintable) browser.click('*[data-id="featureTypeMintable"]')
127+
if (opts.burnable) browser.click('*[data-id="featureTypeBurnable"]')
128+
if (opts.pausable) browser.click('*[data-id="featureTypePausable"]')
129+
if (opts.upgradeability === 'transparent') browser.click('*[data-id="upgradeTypeTransparent"]')
130+
if (opts.upgradeability === 'uups') browser.click('*[data-id="upgradeTypeUups"]')
131+
}
132+
122133
function openTemplatesExplorer(browser: NightwatchBrowser) {
123134
browser
124135
.click('*[data-id="workspacesMenuDropdown"]')
@@ -130,9 +141,9 @@ function runTemplateChecks(
130141
browser: NightwatchBrowser,
131142
start: number,
132143
end: number,
133-
mode: 'create' | 'add' = 'create'
144+
mode: 'create' | 'add' = 'create',
134145
) {
135-
templatesToCheck.slice(start, end).forEach(({ value, displayName, checkSelectors }) => {
146+
templatesToCheck.slice(start, end).forEach(({ value, displayName, checkSelectors, clickOk }) => {
136147
console.log(`Checking template: ${value} in ${mode} mode`)
137148
openTemplatesExplorer(browser)
138149

@@ -159,6 +170,11 @@ function runTemplateChecks(
159170
browser
160171
.waitForElementVisible(`[data-id="add-${value}"]`, 5000)
161172
.click(`[data-id="add-${value}"]`)
173+
if (clickOk) {
174+
browser
175+
.waitForElementVisible('*[data-id="TemplatesSelection-modal-footer-ok-react"]', 2000)
176+
.click('*[data-id="TemplatesSelection-modal-footer-ok-react"]')
177+
}
162178

163179
checkSelectors.forEach(selector => {
164180
console.log(`Checking selector: ${selector}`)
@@ -180,6 +196,41 @@ function runTemplateChecks(
180196
})
181197
}
182198

199+
function testTemplateOptions(browser: NightwatchBrowser, mode: 'create' | 'add') {
200+
openTemplatesExplorer(browser)
201+
202+
const selector = mode === 'create' ? '[data-id="create-ozerc20"]' : '[data-id="add-ozerc20"]'
203+
204+
browser
205+
.waitForElementVisible(selector, 5000)
206+
.click(selector)
207+
208+
browser
209+
.waitForElementVisible('*[data-id="TemplatesSelection-modal-footer-ok-react"]', 2000)
210+
211+
// Simulate user selecting options
212+
setTemplateOptions(browser, { mintable: true, burnable: true, upgradeability: 'uups' })
213+
214+
// Confirm selection
215+
browser
216+
.click('*[data-id="TemplatesSelection-modal-footer-ok-react"]')
217+
218+
// Verify expected file was created
219+
browser
220+
.waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts/MyToken.sol"]', 10000)
221+
.click('*[data-id="treeViewLitreeViewItemcontracts/MyToken.sol"]')
222+
.pause(1000)
223+
.getEditorValue(editorValue => {
224+
const expected = 'contract MyToken is Initializable, ERC20Upgradeable, ERC20BurnableUpgradeable, OwnableUpgradeable, ERC20PermitUpgradeable, UUPSUpgradeable'
225+
if (editorValue.includes(expected)) {
226+
console.log(`✅ Template with options applied successfully (${mode})`)
227+
browser.assert.ok(true, `Template with options applied successfully (${mode})`)
228+
} else {
229+
browser.assert.fail(`❌ Template with options was not applied correctly (${mode})`)
230+
}
231+
})
232+
}
233+
183234
module.exports = {
184235
'@disabled': true,
185236
before: function (browser: NightwatchBrowser, done: VoidFunction) {
@@ -191,7 +242,22 @@ module.exports = {
191242
'Loop through templates and click create #group1': function (browser) {
192243
runTemplateChecks(browser, 0, templatesToCheck.length, 'create')
193244
},
194-
'Loop through templates and click add buttons #group2': function (browser) {
245+
'Loop through templates and click add buttons #group1': function (browser) {
195246
runTemplateChecks(browser, 0, templatesToCheck.length, 'add')
247+
},
248+
'Test template options with create #group2': function (browser: NightwatchBrowser) {
249+
testTemplateOptions(browser, 'create')
250+
},
251+
252+
'Test template options with add #group2': function (browser: NightwatchBrowser) {
253+
openTemplatesExplorer(browser)
254+
browser
255+
.waitForElementVisible(`[data-id="create-remixDefault"]`, 5000)
256+
.click(`[data-id="create-remixDefault"]`)
257+
.waitForElementVisible('*[data-id="TemplatesSelection-modal-footer-ok-react"]', 2000)
258+
.click('*[data-id="TemplatesSelection-modal-footer-ok-react"]')
259+
.pause(1000)
260+
261+
testTemplateOptions(browser, 'add')
196262
}
197263
}

apps/remix-ide/src/app/plugins/templates-selection/templates-selection-plugin.tsx

Lines changed: 76 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ import { RemixUIGridView } from '@remix-ui/remix-ui-grid-view'
99
import { RemixUIGridSection } from '@remix-ui/remix-ui-grid-section'
1010
import { RemixUIGridCell } from '@remix-ui/remix-ui-grid-cell'
1111
import isElectron from 'is-electron'
12-
import type { TemplateGroup } from '@remix-ui/workspace'
12+
import type { Template, TemplateGroup } from '@remix-ui/workspace'
1313
import './templates-selection-plugin.css'
1414
import { templates } from './templates'
1515
import { TEMPLATE_METADATA } from '@remix-ui/workspace'
16+
import { TemplateType } from 'libs/remix-ui/workspace/src/lib/types'
1617

1718
//@ts-ignore
1819
const _paq = (window._paq = window._paq || [])
@@ -88,27 +89,54 @@ export class TemplatesSelectionPlugin extends ViewPlugin {
8889

8990
}
9091

91-
const createWorkspace = async (item, templateName: string) => {
92+
const createWorkspace = async (item: Template, templateGroup: TemplateGroup) => {
9293
const defaultName = await this.call('filePanel', 'getAvailableWorkspaceName', item.displayName)
9394
const username = await this.call('settings', 'get', 'settings/github-user-name')
9495
const email = await this.call('settings', 'get', 'settings/github-email')
9596
const gitNotSet = !username || !email
9697
let workspaceName = defaultName
9798
let initGit = false
99+
this.opts = {}
98100
const modal: AppModal = {
99101
id: 'TemplatesSelection',
100102
title: window._intl.formatMessage({ id: !isElectron() ? 'filePanel.workspace.create' : 'filePanel.workspace.create.desktop' }),
101-
message: await createModalMessage(defaultName, gitNotSet, (value) => workspaceName = value, (value) => initGit = !!value, (event) => setCheckBoxRefs(event), (event) => setRadioRefs(event), templateName),
103+
message: await createModalMessage(
104+
item,
105+
templateGroup,
106+
defaultName,
107+
gitNotSet,
108+
(value) => workspaceName = value,
109+
(value) => initGit = !!value,
110+
(event) => setCheckBoxRefs(event),
111+
(event) => setRadioRefs(event),
112+
),
102113
okLabel: window._intl.formatMessage({ id: !isElectron() ? 'filePanel.ok' : 'filePanel.selectFolder' }),
103114
}
115+
104116
const modalResult = await this.call('notification', 'modal', modal)
117+
console.log('Creating workspace with template', item, this.opts)
105118
if (!modalResult) return
106119
_paq.push(['trackEvent', 'template-selection', 'createWorkspace', item.value])
107120
this.emit('createWorkspaceReducerEvent', workspaceName, item.value, this.opts, false, errorCallback, initGit)
108121
}
109122

110-
const addToCurrentWorkspace = async (item) => {
123+
const addToCurrentWorkspace = async (item: Template, templateGroup: TemplateGroup) => {
124+
this.opts = {}
111125
_paq.push(['trackEvent', 'template-selection', 'addToCurrentWorkspace', item.value])
126+
if (templateGroup.hasOptions) {
127+
const modal: AppModal = {
128+
id: 'TemplatesSelection',
129+
title: window._intl.formatMessage({ id: 'filePanel.customizeTemplate' }),
130+
message: createOptionsModal(
131+
(event) => setCheckBoxRefs(event),
132+
(event) => setRadioRefs(event),),
133+
okLabel: window._intl.formatMessage({ id: 'filePanel.ok' }),
134+
cancelLabel: window._intl.formatMessage({ id: 'filePanel.cancel' })
135+
}
136+
const modalResult = await this.call('notification', 'modal', modal)
137+
if (!modalResult) return
138+
}
139+
console.log('Adding template to current workspace', item, this.opts)
112140
this.emit('addTemplateToWorkspaceReducerEvent', item.value, this.opts, false, async (e, data) => {
113141
if (e) {
114142
const modal: AppModal = {
@@ -208,7 +236,7 @@ export class TemplatesSelectionPlugin extends ViewPlugin {
208236
<span
209237
data-id={`create-${item.value}${item.opts ? JSON.stringify(item.opts) : ''}`}
210238
onClick={async () => {
211-
createWorkspace(item, template.name)
239+
createWorkspace(item, template)
212240
}}
213241
className="btn btn-sm mr-2 border border-primary"
214242
>
@@ -223,7 +251,7 @@ export class TemplatesSelectionPlugin extends ViewPlugin {
223251
>
224252
<span
225253
data-id={`add-${item.value}`}
226-
onClick={async () => addToCurrentWorkspace(item)}
254+
onClick={async () => addToCurrentWorkspace(item, template)}
227255
className="btn btn-sm border"
228256
>
229257
Add to current
@@ -257,13 +285,14 @@ export class TemplatesSelectionPlugin extends ViewPlugin {
257285
}
258286

259287
const createModalMessage = async (
288+
template: Template,
289+
templateGroup: TemplateGroup,
260290
defaultName: string,
261291
gitConfigNotSet: boolean,
262292
onChangeTemplateName: (name: string) => void,
263293
onChangeInitGit: (name: string) => void,
264294
onChangeCheckBoxRefs: (event: any) => void,
265295
onChangeRadioRefs: (event: any) => void,
266-
templateName?: string
267296
) => {
268297
return (
269298
<>
@@ -278,57 +307,7 @@ const createModalMessage = async (
278307
onChange={(e) => onChangeTemplateName(e.target.value)}
279308
onInput={(e) => onChangeTemplateName((e.target as any).value)}
280309
/>
281-
{templateName?.includes('OpenZeppelin') ? (
282-
<div id="ozcustomization" data-id="ozCustomization" style={{ display: 'block' }} className="mb-2">
283-
<label className="form-check-label d-block mb-2" style={{ fontWeight: 'bolder' }}>
284-
<FormattedMessage id="filePanel.customizeTemplate" />
285-
</label>
286-
287-
<label id="wsName" className="form-check-label d-block mb-1">
288-
<FormattedMessage id="filePanel.features" />
289-
</label>
290-
<div className="mb-2">
291-
<div className="d-flex ml-2 custom-control custom-checkbox">
292-
<input className="custom-control-input" type="checkbox" name="feature" value="mintable" id="mintable" onChange={onChangeCheckBoxRefs} />
293-
<label className="form-check-label custom-control-label" htmlFor="mintable" data-id="featureTypeMintable">
294-
<FormattedMessage id="filePanel.mintable" />
295-
</label>
296-
</div>
297-
<div className="d-flex ml-2 custom-control custom-checkbox">
298-
<input className="custom-control-input" type="checkbox" name="feature" value="burnable" id="burnable" onChange={onChangeCheckBoxRefs} />
299-
<label className="form-check-label custom-control-label" htmlFor="burnable" data-id="featureTypeBurnable">
300-
<FormattedMessage id="filePanel.burnable" />
301-
</label>
302-
</div>
303-
<div className="d-flex ml-2 custom-control custom-checkbox">
304-
<input className="custom-control-input" type="checkbox" name="feature" value="pausable" id="pausable" onChange={onChangeCheckBoxRefs} />
305-
<label className="form-check-label custom-control-label" htmlFor="pausable" data-id="featureTypePausable">
306-
<FormattedMessage id="filePanel.pausable" />
307-
</label>
308-
</div>
309-
</div>
310-
311-
<label id="wsName" className="form-check-label d-block mb-1">
312-
<FormattedMessage id="filePanel.upgradeability" />
313-
</label>
314-
<div>
315-
<div className="d-flex ml-2 custom-control custom-radio">
316-
<input className="custom-control-input" type="radio" name="upgradeability" value="transparent" id="transparent" onChange={onChangeRadioRefs} />
317-
<label className="form-check-label custom-control-label" htmlFor="transparent" data-id="upgradeTypeTransparent">
318-
<FormattedMessage id="filePanel.transparent" />
319-
</label>
320-
</div>
321-
<div className="d-flex ml-2 custom-control custom-radio">
322-
<input className="custom-control-input" type="radio" name="upgradeability" value="uups" id="uups" onChange={onChangeRadioRefs} />
323-
<label className="form-check-label custom-control-label" htmlFor="uups" data-id="upgradeTypeUups">
324-
UUPS
325-
</label>
326-
</div>
327-
</div>
328-
</div>
329-
) : (
330-
<></>
331-
)}
310+
{templateGroup.hasOptions ? createOptionsModal(onChangeCheckBoxRefs, onChangeRadioRefs) : null}
332311
<div className="d-flex py-2 align-items-center custom-control custom-checkbox">
333312
<input
334313
id="initGitRepository"
@@ -359,3 +338,42 @@ const createModalMessage = async (
359338
)
360339
}
361340

341+
const createOptionsModal = (
342+
onChangeCheckBoxRefs: (event: any) => void,
343+
onChangeRadioRefs: (event: any) => void
344+
) => (
345+
<div id="ozcustomization" data-id="ozCustomization" style={{ display: 'block' }} className="mb-2">
346+
<label className="form-check-label d-block mb-2" style={{ fontWeight: 'bolder' }}>
347+
<FormattedMessage id="filePanel.customizeTemplate" />
348+
</label>
349+
350+
<label className="form-check-label d-block mb-1">
351+
<FormattedMessage id="filePanel.features" />
352+
</label>
353+
<div className="mb-2">
354+
{['mintable', 'burnable', 'pausable'].map((feature) => (
355+
<div key={feature} className="d-flex ml-2 custom-control custom-checkbox">
356+
<input className="custom-control-input" type="checkbox" name="feature" value={feature} id={feature} onChange={onChangeCheckBoxRefs} />
357+
<label className="form-check-label custom-control-label" htmlFor={feature} data-id={`featureType${feature.charAt(0).toUpperCase() + feature.slice(1)}`}>
358+
<FormattedMessage id={`filePanel.${feature}`} />
359+
</label>
360+
</div>
361+
))}
362+
</div>
363+
364+
<label className="form-check-label d-block mb-1">
365+
<FormattedMessage id="filePanel.upgradeability" />
366+
</label>
367+
<div>
368+
{['transparent', 'uups'].map((type) => (
369+
<div key={type} className="d-flex ml-2 custom-control custom-radio">
370+
<input className="custom-control-input" type="radio" name="upgradeability" value={type} id={type} onChange={onChangeRadioRefs} />
371+
<label className="form-check-label custom-control-label" htmlFor={type} data-id={`upgradeType${type.charAt(0).toUpperCase() + type.slice(1)}`}>
372+
{type.toUpperCase()}
373+
</label>
374+
</div>
375+
))}
376+
</div>
377+
</div>
378+
)
379+

apps/remix-ide/src/app/plugins/templates-selection/templates.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export const templates = (intl: any, plugin: any): TemplateGroup[] => {
1414
},
1515
{
1616
name: "OpenZeppelin",
17+
hasOptions: true,
1718
items: [
1819
{
1920
value: "ozerc20",

libs/remix-ui/workspace/src/lib/utils/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,5 +183,6 @@ export type TemplateGroup = {
183183
onClickLabel?: string
184184
description?: string
185185
IsArtefact?: boolean
186+
hasOptions?: boolean
186187
}
187188

0 commit comments

Comments
 (0)