@@ -61,6 +61,13 @@ const USER_B_SESSION = {
6161 * does not include `info.x-smoke-test-marker`, so once our custom ruleset is
6262 * uploaded the rule defined in fixtures/files/custom.spectral.yaml will fire.
6363 */
64+ async function expandLintPanel ( page : Page ) {
65+ const lintButton = page . getByTestId ( 'lint-panel-toggle' ) ;
66+ await expect . soft ( lintButton ) . toBeVisible ( { timeout : 15_000 } ) ;
67+ await lintButton . click ( ) ;
68+ await expect . soft ( page . getByTestId ( 'lint-panel' ) ) . toBeAttached ( { timeout : 15_000 } ) ;
69+ }
70+
6471async function openPetStoreDesignDoc ( page : Page ) {
6572 await page . getByRole ( 'button' , { name : 'Create document' } ) . click ( ) ;
6673 await page . getByRole ( 'dialog' ) . getByRole ( 'button' , { name : 'Create' } ) . click ( ) ;
@@ -73,7 +80,9 @@ async function uploadRuleset(insomnia: InsomniaApp, page: Page) {
7380 await insomnia . queueOpenDialogResponse ( [ RULESET_FIXTURE ] ) ;
7481 await page . getByLabel ( 'Upload custom ruleset' ) . click ( ) ;
7582 // Soft assert per ESLint rule; a failure here will surface downstream as well.
76- await expect . soft ( page . getByRole ( 'button' , { name : 'View selected ruleset content' } ) ) . toBeVisible ( { timeout : 10_000 } ) ;
83+ await expect
84+ . soft ( page . getByRole ( 'button' , { name : 'View selected ruleset content' } ) )
85+ . toBeVisible ( { timeout : 10_000 } ) ;
7786}
7887
7988async function removeRuleset ( page : Page ) {
@@ -112,7 +121,10 @@ async function createGitDesignDocument(insomnia: InsomniaApp, page: Page, projec
112121 await page . getByRole ( 'textbox' , { name : 'Name' , exact : true } ) . fill ( 'Lint Test Spec' ) ;
113122 await page . getByRole ( 'textbox' , { name : / F i l e n a m e / } ) . fill ( 'lint_test_spec' ) ;
114123 await page . getByRole ( 'button' , { name : 'Create' , exact : true } ) . click ( ) ;
115- await page . getByRole ( 'dialog' ) . waitFor ( { state : 'hidden' , timeout : 10_000 } ) . catch ( ( ) => { } ) ;
124+ await page
125+ . getByRole ( 'dialog' )
126+ . waitFor ( { state : 'hidden' , timeout : 10_000 } )
127+ . catch ( ( ) => { } ) ;
116128 // Populate with Pet Store example so the lint panel renders (requires non-empty apiSpec.contents).
117129 await page . getByText ( 'Use example' ) . click ( ) ;
118130 await page . getByText ( 'Pet Store' ) . click ( ) ;
@@ -159,10 +171,16 @@ test.describe('Custom Spectral Lint Rules', () => {
159171 await uploadRuleset ( insomnia , insomnia . page ) ;
160172
161173 // Our custom rule should now fire on Pet Store.
174+ await expandLintPanel ( insomnia . page ) ;
162175 await expect . soft ( insomnia . page . getByText ( new RegExp ( RULESET_RULE_NAME ) ) ) . toBeVisible ( {
163176 timeout : 15_000 ,
164177 } ) ;
165178
179+ // Capture error/warning counts before relaunch so we can assert persistence.
180+ const lintToggle = insomnia . page . getByTestId ( 'lint-panel-toggle' ) ;
181+ await expect . soft ( lintToggle ) . toBeVisible ( { timeout : 15_000 } ) ;
182+ const lintSummaryBefore = await lintToggle . textContent ( ) ;
183+
166184 // Close the Electron process and relaunch it against the same data path.
167185 // This exercises the full persistence boundary: NeDB on disk, main-process
168186 // startup, renderer init, clientLoader.
@@ -175,9 +193,10 @@ test.describe('Custom Spectral Lint Rules', () => {
175193 await expect
176194 . soft ( insomnia . page . getByRole ( 'button' , { name : 'View selected ruleset content' } ) )
177195 . toBeVisible ( { timeout : 15_000 } ) ;
178- await expect . soft ( insomnia . page . getByText ( new RegExp ( RULESET_RULE_NAME ) ) ) . toBeVisible ( {
179- timeout : 15_000 ,
180- } ) ;
196+
197+ // Assert same error/warning counts as before relaunch (ruleset persisted).
198+ const lintToggleAfter = insomnia . page . getByTestId ( 'lint-panel-toggle' ) ;
199+ await expect . soft ( lintToggleAfter ) . toHaveText ( lintSummaryBefore ?? '' , { timeout : 15_000 } ) ;
181200 } ) ;
182201
183202 // ---------------------------------------------------------------------------
@@ -186,6 +205,7 @@ test.describe('Custom Spectral Lint Rules', () => {
186205 test ( 'remove custom ruleset reverts to default OAS, persists after app relaunch' , async ( { insomnia } ) => {
187206 await openPetStoreDesignDoc ( insomnia . page ) ;
188207 await uploadRuleset ( insomnia , insomnia . page ) ;
208+ await expandLintPanel ( insomnia . page ) ;
189209 await expect . soft ( insomnia . page . getByText ( new RegExp ( RULESET_RULE_NAME ) ) ) . toBeVisible ( {
190210 timeout : 15_000 ,
191211 } ) ;
@@ -204,7 +224,9 @@ test.describe('Custom Spectral Lint Rules', () => {
204224 // ---------------------------------------------------------------------------
205225 // 3. Invalid ruleset — error modal appears, ruleset is not applied
206226 // ---------------------------------------------------------------------------
207- test ( 'uploading a ruleset with disallowed keys shows an error and leaves default ruleset active' , async ( { insomnia } ) => {
227+ test ( 'uploading a ruleset with disallowed keys shows an error and leaves default ruleset active' , async ( {
228+ insomnia,
229+ } ) => {
208230 await openPetStoreDesignDoc ( insomnia . page ) ;
209231 await expect . soft ( insomnia . page . getByText ( 'Default OAS Ruleset' ) ) . toBeVisible ( ) ;
210232
@@ -218,9 +240,7 @@ test.describe('Custom Spectral Lint Rules', () => {
218240
219241 // Default ruleset should still be active; no custom upload button state change.
220242 await expect . soft ( insomnia . page . getByText ( 'Default OAS Ruleset' ) ) . toBeVisible ( ) ;
221- await expect
222- . soft ( insomnia . page . getByRole ( 'button' , { name : 'View selected ruleset content' } ) )
223- . toBeHidden ( ) ;
243+ await expect . soft ( insomnia . page . getByRole ( 'button' , { name : 'View selected ruleset content' } ) ) . toBeHidden ( ) ;
224244 } ) ;
225245
226246 // ---------------------------------------------------------------------------
@@ -293,9 +313,8 @@ test.describe('Custom Spectral Lint Rules', () => {
293313 await expect
294314 . soft ( machineB . page . getByRole ( 'button' , { name : 'View selected ruleset content' } ) )
295315 . toBeVisible ( { timeout : 15_000 } ) ;
296- await expect
297- . soft ( machineB . page . getByText ( new RegExp ( RULESET_RULE_NAME ) ) )
298- . toBeVisible ( { timeout : 15_000 } ) ;
316+ await expandLintPanel ( machineB . page ) ;
317+ await expect . soft ( machineB . page . getByText ( new RegExp ( RULESET_RULE_NAME ) ) ) . toBeVisible ( { timeout : 15_000 } ) ;
299318
300319 await fetch ( `${ devServerUrl } /__test-config/cloud-sync/reset` , { method : 'POST' } ) ;
301320 } ) ;
@@ -334,9 +353,8 @@ test.describe('Custom Spectral Lint Rules', () => {
334353 await expect
335354 . soft ( userB . page . getByRole ( 'button' , { name : 'View selected ruleset content' } ) )
336355 . toBeVisible ( { timeout : 15_000 } ) ;
337- await expect
338- . soft ( userB . page . getByText ( new RegExp ( RULESET_RULE_NAME ) ) )
339- . toBeVisible ( { timeout : 15_000 } ) ;
356+ await expandLintPanel ( userB . page ) ;
357+ await expect . soft ( userB . page . getByText ( new RegExp ( RULESET_RULE_NAME ) ) ) . toBeVisible ( { timeout : 15_000 } ) ;
340358
341359 await fetch ( `${ devServerUrl } /__test-config/cloud-sync/reset` , { method : 'POST' } ) ;
342360 } ) ;
0 commit comments