mirror of
https://github.com/enso-org/enso.git
synced 2024-12-23 10:42:05 +03:00
b7a8909818
- Improved performance by batching simulatenous node edits, including metadata updates when dragging many selected nodes together. - Updated Vue to new version, allowing us to use `defineModel`. - Fixed #9161 - Unified all handling of auto-blur by making `useAutoBlur` cheap to register - all logic goes through a single window event handler. - Combined all `ResizeObserver`s into one. - Fixed the behaviour of repeated toast messages. Now only the latest compilation status is visible at any given time, and the errors disappear once compilation passes. - Actually fixed broken interaction of node and visualization widths. There no longer is a style feedback loop and the visible node backdrop width no longer jumps or randomly fails to update.
271 lines
8.8 KiB
TypeScript
271 lines
8.8 KiB
TypeScript
import test, { type Locator, type Page } from 'playwright/test'
|
|
import * as actions from './actions'
|
|
import { expect } from './customExpect'
|
|
import { mockMethodCallInfo } from './expressionUpdates'
|
|
import * as locate from './locate'
|
|
|
|
class DropDownLocator {
|
|
readonly dropDown: Locator
|
|
readonly items: Locator
|
|
|
|
constructor(page: Page) {
|
|
this.dropDown = page.locator('.dropdownContainer')
|
|
this.items = this.dropDown.locator('.selectable-item, .selected-item')
|
|
}
|
|
|
|
async expectVisibleWithOptions(page: Page, options: string[]): Promise<void> {
|
|
await expect(this.dropDown).toBeVisible()
|
|
for (const option of options) {
|
|
await expect(
|
|
this.items.filter({ has: page.getByText(option, { exact: true }) }),
|
|
).toBeVisible()
|
|
}
|
|
await expect(this.items).toHaveCount(options.length)
|
|
}
|
|
|
|
async clickOption(page: Page, option: string): Promise<void> {
|
|
await this.items.filter({ has: page.getByText(option) }).click()
|
|
}
|
|
}
|
|
|
|
test('Widget in plain AST', async ({ page }) => {
|
|
await actions.goToGraph(page)
|
|
const numberNode = locate.graphNodeByBinding(page, 'five')
|
|
const numberWidget = numberNode.locator('.WidgetNumber')
|
|
await expect(numberWidget).toBeVisible()
|
|
await expect(numberWidget.locator('input')).toHaveValue('5')
|
|
|
|
const listNode = locate.graphNodeByBinding(page, 'list')
|
|
const listWidget = listNode.locator('.WidgetVector')
|
|
await expect(listWidget).toBeVisible()
|
|
|
|
const textNode = locate.graphNodeByBinding(page, 'text')
|
|
const textWidget = textNode.locator('.WidgetText')
|
|
await expect(textWidget).toBeVisible()
|
|
await expect(textWidget.locator('input')).toHaveValue('test')
|
|
})
|
|
|
|
test('Selection widgets in Data.read node', async ({ page }) => {
|
|
await actions.goToGraph(page)
|
|
await mockMethodCallInfo(page, 'data', {
|
|
methodPointer: {
|
|
module: 'Standard.Base.Data',
|
|
definedOnType: 'Standard.Base.Data',
|
|
name: 'read',
|
|
},
|
|
notAppliedArguments: [0, 1, 2],
|
|
})
|
|
|
|
const dropDown = new DropDownLocator(page)
|
|
|
|
// Check initially visible arguments
|
|
const node = locate.graphNodeByBinding(page, 'data')
|
|
const argumentNames = node.locator('.WidgetArgumentName')
|
|
await expect(argumentNames).toHaveCount(1)
|
|
|
|
// Check arguments after selecting node
|
|
await node.click()
|
|
await expect(argumentNames).toHaveCount(3)
|
|
|
|
// Set value on `on_problems` (static drop-down)
|
|
const onProblemsArg = argumentNames.filter({ has: page.getByText('on_problems') })
|
|
await onProblemsArg.click()
|
|
await dropDown.expectVisibleWithOptions(page, ['Ignore', 'Report_Warning', 'Report_Error'])
|
|
await dropDown.clickOption(page, 'Report_Error')
|
|
await expect(onProblemsArg.locator('.WidgetToken')).toContainText([
|
|
'Problem_Behavior',
|
|
'.',
|
|
'Report_Error',
|
|
])
|
|
|
|
// Change value on `on_problems`
|
|
await mockMethodCallInfo(page, 'data', {
|
|
methodPointer: {
|
|
module: 'Standard.Base.Data',
|
|
definedOnType: 'Standard.Base.Data',
|
|
name: 'read',
|
|
},
|
|
notAppliedArguments: [0, 1],
|
|
})
|
|
await page.getByText('Report_Error').click()
|
|
await dropDown.expectVisibleWithOptions(page, ['Ignore', 'Report_Warning', 'Report_Error'])
|
|
await dropDown.clickOption(page, 'Report_Warning')
|
|
await expect(onProblemsArg.locator('.WidgetToken')).toContainText([
|
|
'Problem_Behavior',
|
|
'.',
|
|
'Report_Warning',
|
|
])
|
|
|
|
// Set value on `path` (dynamic config)
|
|
const pathArg = argumentNames.filter({ has: page.getByText('path') })
|
|
await pathArg.click()
|
|
await expect(page.locator('.dropdownContainer')).toBeVisible()
|
|
await dropDown.expectVisibleWithOptions(page, ['"File 1"', '"File 2"'])
|
|
await dropDown.clickOption(page, '"File 2"')
|
|
await expect(pathArg.locator('.WidgetText > input')).toHaveValue('File 2')
|
|
|
|
// Change value on `path` (dynamic config)
|
|
await mockMethodCallInfo(page, 'data', {
|
|
methodPointer: {
|
|
module: 'Standard.Base.Data',
|
|
definedOnType: 'Standard.Base.Data',
|
|
name: 'read',
|
|
},
|
|
notAppliedArguments: [1],
|
|
})
|
|
await page.getByText('path').click()
|
|
await dropDown.expectVisibleWithOptions(page, ['"File 1"', '"File 2"'])
|
|
await dropDown.clickOption(page, '"File 1"')
|
|
await expect(pathArg.locator('.WidgetText > input')).toHaveValue('File 1')
|
|
})
|
|
|
|
test('Managing aggregates in `aggregate` node', async ({ page }) => {
|
|
await actions.goToGraph(page)
|
|
await mockMethodCallInfo(page, 'aggregated', {
|
|
methodPointer: {
|
|
module: 'Standard.Table.Data.Table',
|
|
definedOnType: 'Standard.Table.Data.Table.Table',
|
|
name: 'aggregate',
|
|
},
|
|
notAppliedArguments: [1, 2, 3],
|
|
})
|
|
const dropDown = new DropDownLocator(page)
|
|
|
|
// Check initially visible arguments
|
|
const node = locate.graphNodeByBinding(page, 'aggregated')
|
|
const argumentNames = node.locator('.WidgetArgumentName')
|
|
await expect(argumentNames).toHaveCount(1)
|
|
|
|
// Check arguments after selecting node
|
|
await node.click()
|
|
await expect(argumentNames).toHaveCount(3)
|
|
|
|
// Add first aggregate
|
|
const columnsArg = argumentNames.filter({ has: page.getByText('columns') })
|
|
await columnsArg.locator('.add-item').click()
|
|
await expect(columnsArg.locator('.WidgetToken')).toContainText([
|
|
'Aggregate_Column',
|
|
'.',
|
|
'Group_By',
|
|
])
|
|
await mockMethodCallInfo(
|
|
page,
|
|
{
|
|
binding: 'aggregated',
|
|
expr: 'Aggregate_Column.Group_By',
|
|
},
|
|
{
|
|
methodPointer: {
|
|
module: 'Standard.Table.Data.Aggregate_Column',
|
|
definedOnType: 'Standard.Table.Data.Aggregate_Column.Aggregate_Column',
|
|
name: 'Group_By',
|
|
},
|
|
notAppliedArguments: [0, 1],
|
|
},
|
|
)
|
|
|
|
// Change aggregation type
|
|
const firstItem = columnsArg.locator('.item > .WidgetPort > .WidgetSelection')
|
|
await firstItem.click()
|
|
await dropDown.expectVisibleWithOptions(page, ['Group_By', 'Count', 'Count_Distinct'])
|
|
await dropDown.clickOption(page, 'Count_Distinct')
|
|
await expect(columnsArg.locator('.WidgetToken')).toContainText([
|
|
'Aggregate_Column',
|
|
'.',
|
|
'Count_Distinct',
|
|
])
|
|
await mockMethodCallInfo(
|
|
page,
|
|
{
|
|
binding: 'aggregated',
|
|
expr: 'Aggregate_Column.Count_Distinct',
|
|
},
|
|
{
|
|
methodPointer: {
|
|
module: 'Standard.Table.Data.Aggregate_Column',
|
|
definedOnType: 'Standard.Table.Data.Aggregate_Column.Aggregate_Column',
|
|
name: 'Count_Distinct',
|
|
},
|
|
notAppliedArguments: [0, 1, 2],
|
|
},
|
|
)
|
|
|
|
// Set column
|
|
const columnArg = firstItem.locator('.WidgetSelection').first()
|
|
await columnArg.click()
|
|
await dropDown.expectVisibleWithOptions(page, ['"column 1"', '"column 2"'])
|
|
await dropDown.clickOption(page, '"column 1"')
|
|
await expect(columnsArg.locator('.WidgetToken')).toContainText([
|
|
'Aggregate_Column',
|
|
'.',
|
|
'Count_Distinct',
|
|
])
|
|
await expect(columnsArg.locator('.WidgetText > input').first()).toHaveValue('column 1')
|
|
|
|
// Add another aggregate
|
|
await columnsArg.locator('.add-item').click()
|
|
await expect(columnsArg.locator('.WidgetToken')).toContainText([
|
|
'Aggregate_Column',
|
|
'.',
|
|
'Count_Distinct',
|
|
'Aggregate_Column',
|
|
'.',
|
|
'Group_By',
|
|
])
|
|
await mockMethodCallInfo(
|
|
page,
|
|
{
|
|
binding: 'aggregated',
|
|
expr: 'Aggregate_Column.Group_By',
|
|
},
|
|
{
|
|
methodPointer: {
|
|
module: 'Standard.Table.Data.Aggregate_Column',
|
|
definedOnType: 'Standard.Table.Data.Aggregate_Column.Aggregate_Column',
|
|
name: 'Group_By',
|
|
},
|
|
notAppliedArguments: [0, 1],
|
|
},
|
|
)
|
|
|
|
// Set new aggregate's column
|
|
const secondItem = columnsArg.locator('.item > .WidgetPort > .WidgetSelection').nth(1)
|
|
const secondColumnArg = secondItem.locator('.WidgetSelection').first()
|
|
await secondColumnArg.click()
|
|
await dropDown.expectVisibleWithOptions(page, ['"column 1"', '"column 2"'])
|
|
await dropDown.clickOption(page, '"column 2"')
|
|
await expect(secondItem.locator('.WidgetToken')).toContainText([
|
|
'Aggregate_Column',
|
|
'.',
|
|
'Group_By',
|
|
])
|
|
await expect(secondItem.locator('.WidgetText > input').first()).toHaveValue('column 2')
|
|
|
|
// Switch aggregates
|
|
//TODO[ao] I have no idea how to emulate drag. Simple dragTo does not work (some element seem to capture event).
|
|
// When hovered, the handle becomes available after some time, but still mouse events don't have any effect.
|
|
// I have no time now to investigate this.
|
|
// Once fixed, add also removing element from vector here.
|
|
|
|
// await columnsArg.locator('.item > .handle').nth(1).hover({ force: true })
|
|
// await columnsArg.locator('.item > .handle').nth(1).hover()
|
|
// await page.mouse.down()
|
|
// await columnsArg.locator('.item > .handle').nth(0).hover({ force: true })
|
|
// await columnsArg.locator('.item > .handle').nth(0).hover()
|
|
// await page.mouse.up()
|
|
// await expect(columnsArg.locator('.WidgetToken')).toContainText([
|
|
// 'Aggregate_Column',
|
|
// '.',
|
|
// 'Group_By',
|
|
// '"',
|
|
// 'column 2',
|
|
// '"',
|
|
// 'Aggregate_Column',
|
|
// '.',
|
|
// 'Count_Distinct',
|
|
// '"',
|
|
// 'column 1',
|
|
// '"',
|
|
// ])
|
|
})
|