Skip to content

Commit f863af9

Browse files
authored
chore: added boolean table editor tests (supabase#40954)
added boolean table editor tests
1 parent ae727a4 commit f863af9

File tree

1 file changed

+219
-0
lines changed

1 file changed

+219
-0
lines changed

e2e/studio/features/table-editor.spec.ts

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,4 +779,223 @@ test.describe('table editor', () => {
779779
// Cleanup
780780
await deleteTable(page, ref, tableName)
781781
})
782+
783+
test('boolean fields can be edited correctly', async ({ page, ref }) => {
784+
const tableName = 'pw_table_boolean_edits'
785+
const boolColName = 'is_active'
786+
787+
if (!page.url().includes('/editor')) {
788+
await page.goto(toUrl(`/project/${ref}/editor?schema=public`))
789+
await waitForTableToLoad(page, ref)
790+
}
791+
792+
await dismissToastsIfAny(page)
793+
794+
// Create a simple table with a boolean column
795+
await page.getByRole('button', { name: 'New table', exact: true }).click()
796+
await page.getByTestId('table-name-input').fill(tableName)
797+
await page.getByTestId('created_at-extra-options').click()
798+
await page.getByRole('checkbox', { name: 'Is Nullable' }).click()
799+
await page.getByTestId('created_at-extra-options').click({ force: true })
800+
801+
// Add boolean column
802+
await page.getByRole('button', { name: 'Add column' }).click()
803+
await page.getByRole('textbox', { name: 'column_name' }).fill(boolColName)
804+
await page.getByText('Choose a column type...').click()
805+
await page.getByPlaceholder('Search types...').fill('bool')
806+
await page.getByRole('option', { name: 'bool' }).first().click()
807+
808+
await page.getByRole('button', { name: 'Save' }).click()
809+
await expect(
810+
page.getByText(`Table ${tableName} is good to go!`),
811+
'Success toast should be visible after table creation'
812+
).toBeVisible({ timeout: 50000 })
813+
814+
await expect(
815+
page.getByRole('button', { name: `View ${tableName}`, exact: true }),
816+
'Table should be visible after creation'
817+
).toBeVisible()
818+
819+
// Navigate to the table
820+
await page.getByRole('button', { name: `View ${tableName}`, exact: true }).click()
821+
await page.waitForURL(/\/editor\/\d+\?schema=public$/)
822+
823+
// Insert a row with TRUE value via side panel
824+
await page.getByTestId('table-editor-insert-new-row').click()
825+
await page.getByRole('menuitem', { name: 'Insert row Insert a new row' }).click()
826+
await page.getByRole('combobox').click()
827+
await page.getByRole('option', { name: 'TRUE' }).click()
828+
await page.getByTestId('action-bar-save-row').click()
829+
await waitForApiResponse(page, 'pg-meta', ref, 'query?key=', { method: 'POST' })
830+
831+
await expect(
832+
page.getByRole('gridcell', { name: 'TRUE' }),
833+
'TRUE value should be displayed'
834+
).toBeVisible()
835+
836+
// Insert a row with FALSE value via side panel
837+
await page.getByTestId('table-editor-insert-new-row').click()
838+
await page.getByRole('menuitem', { name: 'Insert row Insert a new row' }).click()
839+
await page.getByRole('combobox').click()
840+
await page.getByRole('option', { name: 'FALSE' }).click()
841+
await page.getByTestId('action-bar-save-row').click()
842+
await waitForApiResponse(page, 'pg-meta', ref, 'query?key=', { method: 'POST' })
843+
844+
// Verify FALSE value is preserved
845+
await expect(
846+
page.getByRole('gridcell', { name: 'FALSE' }),
847+
'FALSE value should be displayed and preserved'
848+
).toBeVisible()
849+
850+
// Edit the FALSE value to TRUE using inline editor
851+
const falseCell = page.getByRole('gridcell', { name: 'FALSE' }).first()
852+
await falseCell.dblclick()
853+
854+
// Wait for boolean editor dropdown to appear
855+
const booleanEditor = page.locator('#boolean-editor')
856+
await expect(booleanEditor, 'Boolean editor should be visible').toBeVisible()
857+
858+
// Change from false to true
859+
await booleanEditor.selectOption('true')
860+
const updateTrueResponse = waitForApiResponse(page, 'pg-meta', ref, 'query?key=', {
861+
method: 'POST',
862+
})
863+
await page.getByRole('columnheader', { name: 'id' }).click()
864+
await updateTrueResponse
865+
866+
// Verify the value changed to TRUE (now there should be 2 TRUE values in the table)
867+
await expect(
868+
page.getByRole('gridcell', { name: 'TRUE' }),
869+
'Value should change to TRUE after inline edit'
870+
).toHaveCount(2)
871+
872+
// Edit TRUE value back to FALSE using inline editor
873+
// Use the second TRUE cell (the one we just edited from FALSE to TRUE)
874+
const trueCell = page.getByRole('gridcell', { name: 'TRUE' }).nth(1)
875+
await trueCell.dblclick()
876+
877+
await expect(booleanEditor, 'Boolean editor should be visible for second edit').toBeVisible()
878+
await booleanEditor.selectOption('false')
879+
const updateFalseResponse = waitForApiResponse(page, 'pg-meta', ref, 'query?key=', {
880+
method: 'POST',
881+
})
882+
await page.getByRole('columnheader', { name: 'id' }).click()
883+
await updateFalseResponse
884+
885+
// Verify FALSE value is preserved and not converted to NULL (this is the critical regression test)
886+
const falseCells = page.getByRole('gridcell', { name: 'FALSE' })
887+
await expect(
888+
falseCells.first(),
889+
'FALSE value should be preserved and not become NULL after inline edit'
890+
).toBeVisible()
891+
892+
// Cleanup
893+
await deleteTable(page, ref, tableName)
894+
})
895+
896+
test('nullable boolean fields support NULL values', async ({ page, ref }) => {
897+
const tableName = 'pw_table_boolean_nullable'
898+
const boolColName = 'is_enabled'
899+
900+
if (!page.url().includes('/editor')) {
901+
await page.goto(toUrl(`/project/${ref}/editor?schema=public`))
902+
await waitForTableToLoad(page, ref)
903+
}
904+
905+
await dismissToastsIfAny(page)
906+
907+
// Create a table with a nullable boolean column
908+
await page.getByRole('button', { name: 'New table', exact: true }).click()
909+
await page.getByTestId('table-name-input').fill(tableName)
910+
await page.getByTestId('created_at-extra-options').click()
911+
await page.getByRole('checkbox', { name: 'Is Nullable' }).click()
912+
await page.getByTestId('created_at-extra-options').click({ force: true })
913+
914+
// Add nullable boolean column
915+
await page.getByRole('button', { name: 'Add column' }).click()
916+
await page.getByRole('textbox', { name: 'column_name' }).fill(boolColName)
917+
await page.getByText('Choose a column type...').click()
918+
await page.getByPlaceholder('Search types...').fill('bool')
919+
await page.getByRole('option', { name: 'bool' }).first().click()
920+
921+
await page.getByRole('button', { name: 'Save' }).click()
922+
await expect(
923+
page.getByText(`Table ${tableName} is good to go!`),
924+
'Success toast should be visible after table creation'
925+
).toBeVisible({ timeout: 50000 })
926+
927+
await expect(
928+
page.getByRole('button', { name: `View ${tableName}`, exact: true }),
929+
'Table should be visible after creation'
930+
).toBeVisible()
931+
932+
// Navigate to the table
933+
await page.getByRole('button', { name: `View ${tableName}`, exact: true }).click()
934+
await page.waitForURL(/\/editor\/\d+\?schema=public$/)
935+
936+
// Insert a row with TRUE value
937+
await page.getByTestId('table-editor-insert-new-row').click()
938+
await page.getByRole('menuitem', { name: 'Insert row Insert a new row' }).click()
939+
await page.getByRole('combobox').click()
940+
await page.getByRole('option', { name: 'TRUE' }).click()
941+
await page.getByTestId('action-bar-save-row').click()
942+
await waitForApiResponse(page, 'pg-meta', ref, 'query?key=', { method: 'POST' })
943+
944+
await expect(
945+
page.getByRole('gridcell', { name: 'TRUE' }),
946+
'TRUE value should be displayed'
947+
).toBeVisible()
948+
949+
// Insert a row with FALSE value
950+
await page.getByTestId('table-editor-insert-new-row').click()
951+
await page.getByRole('menuitem', { name: 'Insert row Insert a new row' }).click()
952+
await page.getByRole('combobox').click()
953+
await page.getByRole('option', { name: 'FALSE' }).click()
954+
await page.getByTestId('action-bar-save-row').click()
955+
await waitForApiResponse(page, 'pg-meta', ref, 'query?key=', { method: 'POST' })
956+
957+
await expect(
958+
page.getByRole('gridcell', { name: 'FALSE' }),
959+
'FALSE value should be displayed'
960+
).toBeVisible()
961+
962+
// Edit FALSE to NULL using inline editor
963+
const falseCellToNull = page.getByRole('gridcell', { name: 'FALSE' })
964+
await falseCellToNull.dblclick()
965+
966+
const booleanEditor = page.locator('#boolean-editor')
967+
await expect(booleanEditor, 'Boolean editor should be visible').toBeVisible()
968+
969+
await booleanEditor.selectOption('null')
970+
971+
const updateNullResponse = waitForApiResponse(page, 'pg-meta', ref, 'query?key=', {
972+
method: 'POST',
973+
})
974+
await page.getByRole('columnheader', { name: 'id' }).click()
975+
await updateNullResponse
976+
977+
// Verify value changed to NULL on the second row
978+
const nullCells = page.getByRole('gridcell', { name: 'NULL' })
979+
await expect(nullCells, 'FALSE should change to NULL after inline edit').toBeVisible()
980+
981+
// Edit NULL to FALSE using inline editor
982+
const nullCellToFalse = page.getByRole('gridcell', { name: 'NULL' })
983+
await nullCellToFalse.dblclick()
984+
985+
await booleanEditor.selectOption('false')
986+
987+
const updateFalseResponse = waitForApiResponse(page, 'pg-meta', ref, 'query?key=', {
988+
method: 'POST',
989+
})
990+
await page.getByRole('columnheader', { name: 'id' }).click()
991+
await updateFalseResponse
992+
993+
await expect(
994+
page.getByRole('gridcell', { name: 'FALSE' }),
995+
'NULL should change to FALSE after inline edit'
996+
).toBeVisible()
997+
998+
// Cleanup
999+
await deleteTable(page, ref, tableName)
1000+
})
7821001
})

0 commit comments

Comments
 (0)