2024-11-28 12:14:27 -05:00
import { test , expect , Page } from './zoo-test'
import path from 'path'
2024-08-19 08:58:24 -04:00
import * as fsp from 'fs/promises'
2024-08-23 10:50:40 -04:00
import {
getUtils ,
executorInputPath ,
} from './test-utils'
2024-08-13 00:05:30 -07:00
import { TEST_CODE_TRIGGER_ENGINE_EXPORT_ERROR } from './storageStates'
import { bracket } from 'lib/exampleKcl'
2024-08-07 19:27:32 +10:00
test . describe ( 'Regression tests' , ( ) = > {
// bugs we found that don't fit neatly into other categories
2024-11-28 12:14:27 -05:00
test ( 'bad model has inline error #3251' , async ( { context , page , homePage } ) = > { // because the model has `line([0,0]..` it is valid code, but the model is invalid
// regression test for https://github.com/KittyCAD/modeling-app/issues/3251
// Since the bad model also found as issue with the artifact graph, which in tern blocked the editor diognostics
const u = await getUtils ( page )
await context . addInitScript ( async ( ) = > {
localStorage . setItem (
'persistCode' ,
` sketch2 = startSketchOn("XY")
sketch001 = startSketchAt ( [ - 0 , - 0 ] )
| > line ( [ 0 , 0 ] , % )
| > line ( [ - 4.84 , - 5.29 ] , % )
| > lineTo ( [ profileStartX ( % ) , profileStartY ( % ) ] , % )
| > close ( % ) `
)
2024-08-07 19:27:32 +10:00
} )
2024-11-28 12:14:27 -05:00
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
await u . waitForPageLoad ( )
// error in guter
await expect ( page . locator ( '.cm-lint-marker-error' ) ) . toBeVisible ( )
// error text on hover
await page . hover ( '.cm-lint-marker-error' )
// this is a cryptic error message, fact that all the lines are co-linear from the `line([0,0])` is the issue why
// the close doesn't work
// when https://github.com/KittyCAD/modeling-app/issues/3268 is closed
// this test will need updating
const crypticErrorText = ` ApiError `
await expect ( page . getByText ( crypticErrorText ) . first ( ) ) . toBeVisible ( ) } )
test ( 'user should not have to press down twice in cmdbar' , async ( { page , homePage } ) = > { // because the model has `line([0,0]..` it is valid code, but the model is invalid
// regression test for https://github.com/KittyCAD/modeling-app/issues/3251
// Since the bad model also found as issue with the artifact graph, which in tern blocked the editor diognostics
const u = await getUtils ( page )
await page . addInitScript ( async ( ) = > {
localStorage . setItem (
'persistCode' ,
` sketch001 = startSketchOn('XY')
| > startProfileAt ( [ 82.33 , 238.21 ] , % )
| > angledLine ( [ 0 , 288.63 ] , % , $rectangleSegmentA001 )
| > angledLine ( [
segAng ( rectangleSegmentA001 ) - 90 ,
197.97
] , % , $rectangleSegmentB001 )
| > angledLine ( [
segAng ( rectangleSegmentA001 ) ,
- segLen ( rectangleSegmentA001 )
] , % , $rectangleSegmentC001 )
2024-09-10 12:10:14 +10:00
| > lineTo ( [ profileStartX ( % ) , profileStartY ( % ) ] , % )
2024-11-28 12:14:27 -05:00
| > close ( % )
extrude001 = extrude ( 50 , sketch001 )
`
)
2024-09-10 12:10:14 +10:00
} )
2024-11-28 12:14:27 -05:00
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
await u . waitForPageLoad ( )
await test . step ( 'Check arrow down works' , async ( ) = > {
await page . getByTestId ( 'command-bar-open-button' ) . hover ( )
await page . getByTestId ( 'command-bar-open-button' ) . click ( )
const floppy = page
. getByRole ( 'option' , { name : 'floppy disk arrow Export' } )
await floppy . click ( )
// press arrow down key twice
await page . keyboard . press ( 'ArrowDown' )
await page . waitForTimeout ( 100 )
await page . keyboard . press ( 'ArrowDown' )
// STL is the third option, which makes sense for two arrow downs
await expect ( page . locator ( '[data-headlessui-state="active"]' ) ) . toHaveText (
'STL'
)
await page . keyboard . press ( 'Escape' )
await page . waitForTimeout ( 200 )
await page . keyboard . press ( 'Escape' )
await page . waitForTimeout ( 200 )
2024-08-07 19:27:32 +10:00
} )
2024-11-28 12:14:27 -05:00
await test . step ( 'Check arrow up works' , async ( ) = > {
// theme in test is dark, which is the second option, which means we can test arrow up
await page . getByTestId ( 'command-bar-open-button' ) . click ( )
await page . getByText ( 'The overall appearance of the' ) . click ( )
await page . keyboard . press ( 'ArrowUp' )
await page . waitForTimeout ( 100 )
await expect ( page . locator ( '[data-headlessui-state="active"]' ) ) . toHaveText (
'light'
)
} ) } )
test ( 'executes on load' , async ( { page , homePage } ) = > { const u = await getUtils ( page )
await page . addInitScript ( async ( ) = > {
localStorage . setItem (
'persistCode' ,
` sketch001 = startSketchOn('-XZ')
| > startProfileAt ( [ - 6.95 , 4.98 ] , % )
| > line ( [ 25.1 , 0.41 ] , % )
| > line ( [ 0.73 , - 14.93 ] , % )
| > line ( [ - 23.44 , 0.52 ] , % ) `
)
2024-08-07 19:27:32 +10:00
} )
2024-11-28 12:14:27 -05:00
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
await u . waitForPageLoad ( )
// expand variables section
const variablesTabButton = page . getByTestId ( 'variables-pane-button' )
await variablesTabButton . click ( )
// can find sketch001 in the variables summary (pretty-json-container, makes sure we're not looking in the code editor)
// sketch001 only shows up in the variables summary if it's been executed
await page . waitForFunction ( ( ) = > {
const variablesElement = document . querySelector (
'.pretty-json-container'
) as HTMLDivElement
return variablesElement . innerHTML . includes ( 'sketch001' )
2024-08-07 19:27:32 +10:00
} )
2024-11-28 12:14:27 -05:00
await expect (
page . locator ( '.pretty-json-container >> text=sketch001' )
) . toBeVisible ( ) } )
2024-08-07 19:27:32 +10:00
2024-11-28 12:14:27 -05:00
test ( 're-executes' , async ( { page , homePage } ) = > { const u = await getUtils ( page )
await page . addInitScript ( async ( ) = > {
localStorage . setItem ( 'persistCode' , ` myVar = 5 ` )
2024-08-07 19:27:32 +10:00
} )
2024-11-28 12:14:27 -05:00
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
await u . waitForPageLoad ( )
const variablesTabButton = page . getByTestId ( 'variables-pane-button' )
await variablesTabButton . click ( )
// expect to see "myVar:5"
await expect (
page . locator ( '.pretty-json-container >> text=myVar:5' )
) . toBeVisible ( )
// change 5 to 67
await page . locator ( '#code-mirror-override' ) . getByText ( 'myVar' ) . click ( )
await page . keyboard . press ( 'End' )
await page . keyboard . press ( 'Backspace' )
await page . keyboard . type ( '67' )
await expect (
page . locator ( '.pretty-json-container >> text=myVar:67' )
) . toBeVisible ( ) } )
test ( 'ProgramMemory can be serialised' , async ( { page , homePage } ) = > { const u = await getUtils ( page )
await page . addInitScript ( async ( ) = > {
localStorage . setItem (
'persistCode' ,
` part = startSketchOn('XY')
| > startProfileAt ( [ 0 , 0 ] , % )
| > line ( [ 0 , 1 ] , % )
| > line ( [ 1 , 0 ] , % )
| > line ( [ 0 , - 1 ] , % )
| > close ( % )
| > extrude ( 1 , % )
| > patternLinear3d ( {
axis : [ 1 , 0 , 1 ] ,
repetitions : 3 ,
distance : 6
} , % ) `
)
} )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
const messages : string [ ] = [ ]
// Listen for all console events and push the message text to an array
page . on ( 'console' , ( message ) = > messages . push ( message . text ( ) ) )
await homePage . goToModelingScene ( )
await u . waitForPageLoad ( )
// wait for execution done
await u . openDebugPanel ( )
await u . expectCmdLog ( '[data-message-type="execution-done"]' )
const forbiddenMessages = [ 'cannot serialize tagged newtype variant' ]
forbiddenMessages . forEach ( ( forbiddenMessage ) = > {
messages . forEach ( ( message ) = > {
expect ( message ) . not . toContain ( forbiddenMessage )
} )
} ) } )
// Not relevant to us anymore, or at least for the time being.
test . skip ( 'ensure the Zoo logo is not a link in browser app' , async ( { page , homePage } ) = > { const u = await getUtils ( page )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
await u . waitForPageLoad ( )
const zooLogo = page . locator ( '[data-testid="app-logo"]' )
// Make sure it's not a link
await expect ( zooLogo ) . not . toHaveAttribute ( 'href' ) } )
test ( 'Position _ Is Out Of Range... regression test' , { tag : [ '@skipWin' ] } , async ( { context , page , homePage } ) = > { // SKip on windows, its being weird.
test . skip (
process . platform === 'win32' ,
'This test is being weird on windows'
2024-10-02 11:58:17 -04:00
)
2024-11-28 12:14:27 -05:00
const u = await getUtils ( page )
// const PUR = 400 / 37.5 //pixeltoUnitRatio
await page . setBodyDimensions ( { width : 1200 , height : 500 } )
await context . addInitScript ( async ( ) = > {
localStorage . setItem (
'persistCode' ,
` exampleSketch = startSketchOn("XZ")
| > startProfileAt ( [ 0 , 0 ] , % )
| > angledLine ( { angle : 50 , length : 45 } , % )
| > yLineTo ( 0 , % )
| > close ( % )
| >
example = extrude ( 5 , exampleSketch )
shell ( { faces : [ 'end' ] , thickness : 0.25 } , exampleSketch ) `
)
} )
await expect ( async ( ) = > {
await homePage . goToModelingScene ( )
await u . waitForPageLoad ( )
2024-08-13 00:05:30 -07:00
2024-11-28 12:14:27 -05:00
// error in guter
await expect ( page . locator ( '.cm-lint-marker-error' ) ) . toBeVisible ( {
timeout : 1_000 ,
} )
await page . waitForTimeout ( 200 )
// expect it still to be there (sometimes it just clears for a bit?)
await expect ( page . locator ( '.cm-lint-marker-error' ) ) . toBeVisible ( {
timeout : 1_000 ,
} )
} ) . toPass ( { timeout : 40_000 , intervals : [ 1 _000 ] } )
// error text on hover
await page . hover ( '.cm-lint-marker-error' )
await expect ( page . getByText ( 'Unexpected token: |' ) . first ( ) ) . toBeVisible ( )
// Okay execution finished, let's start editing text below the error.
await u . codeLocator . click ( )
// Go to the end of the editor
// This bug happens when there is a diagnostic in the editor and you try to
// edit text below it.
// Or delete a huge chunk of text and then try to edit below it.
await page . keyboard . press ( 'End' )
await page . keyboard . down ( 'Shift' )
await page . keyboard . press ( 'ArrowUp' )
await page . keyboard . press ( 'ArrowUp' )
await page . keyboard . press ( 'ArrowUp' )
await page . keyboard . press ( 'ArrowUp' )
await page . keyboard . press ( 'ArrowUp' )
await page . keyboard . press ( 'End' )
await page . keyboard . up ( 'Shift' )
await page . keyboard . press ( 'Backspace' )
await expect ( page . locator ( '.cm-lint-marker-error' ) ) . not . toBeVisible ( )
await page . keyboard . press ( 'Enter' )
await page . keyboard . press ( 'Enter' )
await page . keyboard . type ( 'thing: "blah"' , { delay : 100 } )
await page . keyboard . press ( 'Enter' )
await page . keyboard . press ( 'ArrowLeft' )
await expect ( page . locator ( '.cm-content' ) )
. toContainText ( ` exampleSketch = startSketchOn("XZ")
| > startProfileAt ( [ 0 , 0 ] , % )
| > angledLine ( { angle : 50 , length : 45 } , % )
| > yLineTo ( 0 , % )
| > close ( % )
thing : "blah" ` )
await expect ( page . locator ( '.cm-lint-marker-error' ) ) . toBeVisible ( ) } )
test ( 'when engine fails export we handle the failure and alert the user' , async ( { page , homePage } ) = > { const u = await getUtils ( page )
await page . addInitScript (
async ( { code } ) = > {
localStorage . setItem ( 'persistCode' , code )
; ( window as any ) . playwrightSkipFilePicker = true
} ,
{ code : TEST_CODE_TRIGGER_ENGINE_EXPORT_ERROR }
)
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
await u . waitForPageLoad ( )
// wait for execution done
await u . openDebugPanel ( )
await u . expectCmdLog ( '[data-message-type="execution-done"]' )
await u . closeDebugPanel ( )
// expect zero errors in guter
await expect ( page . locator ( '.cm-lint-marker-error' ) ) . not . toBeVisible ( )
// export the model
const exportButton = page . getByTestId ( 'export-pane-button' )
await expect ( exportButton ) . toBeVisible ( )
// Click the export button
await exportButton . click ( )
// Click the stl.
const stlOption = page . getByText ( 'glTF' )
await expect ( stlOption ) . toBeVisible ( )
await page . keyboard . press ( 'Enter' )
// Click the checkbox
const submitButton = page . getByText ( 'Confirm Export' )
await expect ( submitButton ) . toBeVisible ( )
await page . keyboard . press ( 'Enter' )
// Find the toast.
// Look out for the toast message
const exportingToastMessage = page . getByText ( ` Exporting... ` )
const errorToastMessage = page . getByText ( ` Error while exporting ` )
const engineErrorToastMessage = page . getByText ( ` Nothing to export ` )
await expect ( engineErrorToastMessage ) . toBeVisible ( )
// Make sure the exporting toast is gone
await expect ( exportingToastMessage ) . not . toBeVisible ( )
// Click the code editor
await page . locator ( '.cm-content' ) . click ( )
await page . waitForTimeout ( 2000 )
// Expect the toast to be gone
await expect ( errorToastMessage ) . not . toBeVisible ( )
await expect ( engineErrorToastMessage ) . not . toBeVisible ( )
// Now add in code that works.
await page . locator ( '.cm-content' ) . fill ( bracket )
await page . keyboard . press ( 'End' )
await page . keyboard . press ( 'Enter' )
// wait for execution done
await u . openDebugPanel ( )
await u . expectCmdLog ( '[data-message-type="execution-done"]' )
await u . closeDebugPanel ( )
// Now try exporting
// Click the export button
await exportButton . click ( )
// Click the stl.
await expect ( stlOption ) . toBeVisible ( )
await page . keyboard . press ( 'Enter' )
// Click the checkbox
await expect ( submitButton ) . toBeVisible ( )
await page . keyboard . press ( 'Enter' )
// Find the toast.
// Look out for the toast message
await expect ( exportingToastMessage ) . toBeVisible ( )
// Expect it to succeed.
await expect ( exportingToastMessage ) . not . toBeVisible ( { timeout : 15_000 } )
await expect ( errorToastMessage ) . not . toBeVisible ( )
await expect ( engineErrorToastMessage ) . not . toBeVisible ( )
const successToastMessage = page . getByText ( ` Exported successfully ` )
await expect ( successToastMessage ) . toBeVisible ( ) } )
test ( 'ensure you can not export while an export is already going' , { tag : [ '@skipLinux' , '@skipWin' ] } , async ( { page , homePage } ) = > { // This is being weird on ubuntu and windows.
test . skip (
// eslint-disable-next-line jest/valid-title
process . platform === 'linux' || process . platform === 'win32' ,
'This test is being weird on ubuntu'
)
const u = await getUtils ( page )
await test . step ( 'Set up the code and durations' , async ( ) = > {
2024-08-20 20:29:15 +10:00
await page . addInitScript (
async ( { code } ) = > {
localStorage . setItem ( 'persistCode' , code )
; ( window as any ) . playwrightSkipFilePicker = true
} ,
2024-11-28 12:14:27 -05:00
{
code : bracket ,
}
2024-08-20 20:29:15 +10:00
)
2024-11-28 12:14:27 -05:00
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
await u . waitForPageLoad ( )
2024-08-17 14:15:11 -07:00
// wait for execution done
await u . openDebugPanel ( )
await u . expectCmdLog ( '[data-message-type="execution-done"]' )
await u . closeDebugPanel ( )
2024-11-28 12:14:27 -05:00
2024-08-17 14:15:11 -07:00
// expect zero errors in guter
await expect ( page . locator ( '.cm-lint-marker-error' ) ) . not . toBeVisible ( )
2024-11-28 12:14:27 -05:00
} )
const errorToastMessage = page . getByText ( ` Error while exporting ` )
const exportingToastMessage = page . getByText ( ` Exporting... ` )
const engineErrorToastMessage = page . getByText ( ` Nothing to export ` )
const alreadyExportingToastMessage = page . getByText ( ` Already exporting ` )
const successToastMessage = page . getByText ( ` Exported successfully ` )
await test . step ( 'Blocked second export' , async ( ) = > {
await clickExportButton ( page )
await expect ( exportingToastMessage ) . toBeVisible ( )
await clickExportButton ( page )
await test . step ( 'The second export is blocked' , async ( ) = > {
// Find the toast.
// Look out for the toast message
await Promise . all ( [
expect ( exportingToastMessage . first ( ) ) . toBeVisible ( ) ,
expect ( alreadyExportingToastMessage ) . toBeVisible ( ) ,
] )
} )
await test . step ( 'The first export still succeeds' , async ( ) = > {
await Promise . all ( [
expect ( exportingToastMessage ) . not . toBeVisible ( { timeout : 15_000 } ) ,
expect ( errorToastMessage ) . not . toBeVisible ( ) ,
expect ( engineErrorToastMessage ) . not . toBeVisible ( ) ,
expect ( successToastMessage ) . toBeVisible ( { timeout : 15_000 } ) ,
expect ( alreadyExportingToastMessage ) . not . toBeVisible ( {
timeout : 15_000 ,
} ) ,
] )
} )
} )
await test . step ( 'Successful, unblocked export' , async ( ) = > {
// Try exporting again.
await clickExportButton ( page )
2024-08-17 14:15:11 -07:00
// Find the toast.
// Look out for the toast message
await expect ( exportingToastMessage ) . toBeVisible ( )
2024-11-28 12:14:27 -05:00
2024-08-17 14:15:11 -07:00
// Expect it to succeed.
2024-11-28 12:14:27 -05:00
await Promise . all ( [
expect ( exportingToastMessage ) . not . toBeVisible ( ) ,
expect ( errorToastMessage ) . not . toBeVisible ( ) ,
expect ( engineErrorToastMessage ) . not . toBeVisible ( ) ,
expect ( alreadyExportingToastMessage ) . not . toBeVisible ( ) ,
] )
2024-08-17 14:15:11 -07:00
await expect ( successToastMessage ) . toBeVisible ( )
2024-11-28 12:14:27 -05:00
} ) } )
2024-08-19 08:58:24 -04:00
test (
` Network health indicator only appears in modeling view ` ,
{ tag : '@electron' } ,
2024-11-28 12:14:27 -05:00
async ( { context , page } , testInfo ) = > {
await context . folderSetupFn ( async ( dir ) = > {
const bracketDir = path . join ( dir , 'bracket' )
await fsp . mkdir ( bracketDir , { recursive : true } )
await fsp . copyFile (
executorInputPath ( 'focusrite_scarlett_mounting_braket.kcl' ) ,
path . join ( bracketDir , 'main.kcl' )
)
2024-08-19 08:58:24 -04:00
} )
2024-11-28 12:14:27 -05:00
await page . setBodyDimensions ( { width : 1200 , height : 500 } )
2024-08-19 08:58:24 -04:00
const u = await getUtils ( page )
// Locators
const projectsHeading = page . getByRole ( 'heading' , {
name : 'Your projects' ,
} )
const projectLink = page . getByRole ( 'link' , { name : 'bracket' } )
const networkHealthIndicator = page . getByTestId ( 'network-toggle' )
await test . step ( 'Check the home page' , async ( ) = > {
await expect ( projectsHeading ) . toBeVisible ( )
await expect ( projectLink ) . toBeVisible ( )
await expect ( networkHealthIndicator ) . not . toBeVisible ( )
} )
await test . step ( 'Open the project' , async ( ) = > {
await projectLink . click ( )
} )
await test . step ( 'Check the modeling view' , async ( ) = > {
await expect ( networkHealthIndicator ) . toBeVisible ( )
await expect ( networkHealthIndicator ) . toContainText ( 'Problem' )
await u . waitForPageLoad ( )
await expect ( networkHealthIndicator ) . toContainText ( 'Connected' )
} )
}
)
2024-09-23 10:33:47 -04:00
2024-11-28 12:14:27 -05:00
test ( ` View gizmo stays visible even when zoomed out all the way ` , async ( { page , homePage } ) = > { const u = await getUtils ( page )
// Constants and locators
const planeColor : [ number , number , number ] = [ 170 , 220 , 170 ]
const bgColor : [ number , number , number ] = [ 27 , 27 , 27 ]
const middlePixelIsColor = async ( color : [ number , number , number ] ) = > {
return u . getGreatestPixDiff ( { x : 600 , y : 250 } , color )
}
const gizmo = page . locator ( '[aria-label*=gizmo]' )
await test . step ( ` Load an empty file ` , async ( ) = > {
await page . addInitScript ( async ( ) = > {
localStorage . setItem ( 'persistCode' , '' )
2024-09-23 10:33:47 -04:00
} )
2024-11-28 12:14:27 -05:00
await page . setBodyDimensions ( { width : 1200 , height : 500 } )
await homePage . goToModelingScene ( )
await u . waitForPageLoad ( )
await u . closeKclCodePanel ( )
} )
await test . step ( ` Zoom out until you can't see the default planes ` , async ( ) = > {
await expect
. poll ( async ( ) = > middlePixelIsColor ( planeColor ) , {
timeout : 5000 ,
message : 'Plane color is visible' ,
} )
. toBeLessThan ( 15 )
let maxZoomOuts = 10
let middlePixelIsBackgroundColor =
( await middlePixelIsColor ( bgColor ) ) < 10
while ( ! middlePixelIsBackgroundColor && maxZoomOuts > 0 ) {
await page . keyboard . down ( 'Control' )
await page . mouse . move ( 600 , 460 )
await page . mouse . down ( { button : 'right' } )
await page . mouse . move ( 600 , 50 , { steps : 20 } )
await page . mouse . up ( { button : 'right' } )
await page . keyboard . up ( 'Control' )
await page . waitForTimeout ( 100 )
maxZoomOuts --
middlePixelIsBackgroundColor = ( await middlePixelIsColor ( bgColor ) ) < 10
}
expect ( middlePixelIsBackgroundColor , {
message : 'We no longer the default planes' ,
} ) . toBeTruthy ( )
2024-09-23 10:33:47 -04:00
} )
2024-11-28 12:14:27 -05:00
await test . step ( ` Check that the gizmo is still visible ` , async ( ) = > {
await expect ( gizmo ) . toBeVisible ( )
} ) } )
2024-08-07 19:27:32 +10:00
} )
2024-08-14 08:49:00 -07:00
async function clickExportButton ( page : Page ) {
2024-08-15 14:24:27 -04:00
await test . step ( 'Running export flow' , async ( ) = > {
// export the model
const exportButton = page . getByTestId ( 'export-pane-button' )
await expect ( exportButton ) . toBeEnabled ( )
2024-08-14 08:49:00 -07:00
2024-08-15 14:24:27 -04:00
// Click the export button
await exportButton . click ( )
2024-08-14 08:49:00 -07:00
2024-08-19 14:21:34 -07:00
// Click the gltf.
2024-08-15 14:24:27 -04:00
const gltfOption = page . getByRole ( 'option' , { name : 'glTF' } )
await expect ( gltfOption ) . toBeVisible ( )
2024-08-14 08:49:00 -07:00
2024-08-15 14:24:27 -04:00
await page . keyboard . press ( 'Enter' )
2024-08-14 08:49:00 -07:00
2024-08-15 14:24:27 -04:00
// Click the checkbox
const submitButton = page . getByText ( 'Confirm Export' )
await expect ( submitButton ) . toBeVisible ( )
2024-08-14 08:49:00 -07:00
2024-08-15 14:24:27 -04:00
await page . keyboard . press ( 'Enter' )
} )
2024-08-14 08:49:00 -07:00
}