1- import { test , expect , Page } from '../../../playwright' ;
2- import { closeAllCollections , openCollection } from '../../utils/page' ;
3- import { buildCommonLocators } from '../../utils/page/locators' ;
1+ import { test , expect } from '../../../playwright' ;
2+ import {
3+ closeAllCollections ,
4+ buildCommonLocators ,
5+ openExportToPostmanModal ,
6+ closeExportToPostmanModal ,
7+ exportCollectionToPostman
8+ } from '../../utils/page' ;
49import * as fs from 'fs' ;
510import * as nodePath from 'path' ;
611
712const COLLECTION_NAME = 'Export Scripts Collection' ;
813
9- const openExportToPostmanModal = async ( page : Page ) => {
10- const locators = buildCommonLocators ( page ) ;
11-
12- await openCollection ( page , COLLECTION_NAME ) ;
13-
14- const collectionAction = locators . actions . collectionActions ( COLLECTION_NAME ) ;
15- await locators . sidebar . collection ( COLLECTION_NAME ) . hover ( ) ;
16- await expect ( collectionAction ) . toBeVisible ( { timeout : 2000 } ) ;
17- await collectionAction . click ( ) ;
18- await locators . dropdown . item ( 'Share' ) . click ( ) ;
19- await expect ( locators . modal . title ( 'Share Collection' ) ) . toBeVisible ( ) ;
20-
21- await page . getByTestId ( 'export-format-postman' ) . click ( ) ;
22- await locators . modal . button ( 'Proceed' ) . click ( ) ;
23- await expect ( locators . modal . title ( 'Export to Postman' ) ) . toBeVisible ( ) ;
24- } ;
25-
26- // export a collection via Share -> Export to Postman into outputDir and read the file
27- const exportPostmanCollection = async (
28- page : Page ,
29- outputDir : string ,
30- { preserveScripts } : { preserveScripts : boolean }
31- ) => {
32- const locators = buildCommonLocators ( page ) ;
33-
34- await openExportToPostmanModal ( page ) ;
35-
36- await test . step ( 'Set the export location' , async ( ) => {
37- await page . getByLabel ( 'Location' , { exact : true } ) . fill ( outputDir ) ;
38- } ) ;
39-
40- await test . step ( 'Configure preserve scripts' , async ( ) => {
41- if ( preserveScripts ) {
42- // 'Preserve scripts' lives under the modal footer's advanced options
43- await page . getByRole ( 'button' , { name : 'Options' } ) . click ( ) ;
44- await page . getByTestId ( 'show-advanced-options-toggle' ) . click ( ) ;
45- const checkbox = page . getByTestId ( 'preserve-scripts-toggle' ) ;
46- await expect ( checkbox ) . toBeVisible ( ) ;
47- await checkbox . check ( ) ;
48- await expect ( checkbox ) . toBeChecked ( ) ;
49- }
50- } ) ;
51-
52- return await test . step ( 'Export and read the written file' , async ( ) => {
53- await locators . modal . button ( 'Export' ) . click ( ) ;
54- const filePath = nodePath . join ( outputDir , `${ COLLECTION_NAME } .json` ) ;
55- await expect . poll ( ( ) => fs . existsSync ( filePath ) , { timeout : 5000 } ) . toBe ( true ) ;
56- return JSON . parse ( fs . readFileSync ( filePath , 'utf-8' ) ) ;
57- } ) ;
58- } ;
59-
6014const findLoginEvents = ( exported : any ) => {
6115 const login = exported . item . find ( ( i : any ) => i . name === 'Login' ) ;
6216 return {
@@ -66,13 +20,13 @@ const findLoginEvents = (exported: any) => {
6620} ;
6721
6822test . describe ( 'Export Postman Collection - Preserve scripts option' , ( ) => {
69- test . afterAll ( async ( { pageWithUserData : page } ) => {
23+ test . afterEach ( async ( { pageWithUserData : page } ) => {
7024 await closeAllCollections ( page ) ;
7125 } ) ;
7226
7327 test ( 'should export scripts as is when preserve scripts is enabled' , async ( { pageWithUserData : page , createTmpDir } ) => {
7428 const outputDir = await createTmpDir ( 'postman-export' ) ;
75- const exported = await exportPostmanCollection ( page , outputDir , { preserveScripts : true } ) ;
29+ const exported = await exportCollectionToPostman ( page , COLLECTION_NAME , outputDir , { preserveScripts : true } ) ;
7630 const { prerequest, test : testEvent } = findLoginEvents ( exported ) ;
7731
7832 expect ( prerequest . script . exec . join ( '\n' ) ) . toContain ( 'bru.setEnvVar(\'token\', \'abc\')' ) ;
@@ -83,7 +37,7 @@ test.describe('Export Postman Collection - Preserve scripts option', () => {
8337
8438 test ( 'should translate scripts to pm.* by default when preserve scripts is disabled' , async ( { pageWithUserData : page , createTmpDir } ) => {
8539 const outputDir = await createTmpDir ( 'postman-export' ) ;
86- const exported = await exportPostmanCollection ( page , outputDir , { preserveScripts : false } ) ;
40+ const exported = await exportCollectionToPostman ( page , COLLECTION_NAME , outputDir , { preserveScripts : false } ) ;
8741 const { prerequest } = findLoginEvents ( exported ) ;
8842
8943 expect ( prerequest . script . exec . join ( '\n' ) ) . toContain ( 'pm.environment.set' ) ;
@@ -98,10 +52,10 @@ test.describe('Export Postman Collection - Preserve scripts option', () => {
9852 // Pre seed a conflicting file so the export hits the "already exists" path
9953 fs . writeFileSync ( filePath , '{"stale":true}' , 'utf-8' ) ;
10054
101- await openExportToPostmanModal ( page ) ;
55+ await openExportToPostmanModal ( page , COLLECTION_NAME ) ;
10256
10357 await test . step ( 'Exporting over an existing file prompts to replace' , async ( ) => {
104- await page . getByLabel ( 'Location' , { exact : true } ) . fill ( outputDir ) ;
58+ await locators . export . locationInput ( ) . fill ( outputDir ) ;
10559 await locators . modal . button ( 'Export' ) . click ( ) ;
10660 await expect ( page . getByText ( 'Name already exists in this location' ) ) . toBeVisible ( ) ;
10761 await expect ( locators . modal . button ( 'Replace' ) ) . toBeVisible ( ) ;
@@ -123,10 +77,10 @@ test.describe('Export Postman Collection - Preserve scripts option', () => {
12377 test ( 'should require a name and location before exporting' , async ( { pageWithUserData : page } ) => {
12478 const locators = buildCommonLocators ( page ) ;
12579
126- await openExportToPostmanModal ( page ) ;
80+ await openExportToPostmanModal ( page , COLLECTION_NAME ) ;
12781
12882 await test . step ( 'Clearing the name and location blocks export with validation errors' , async ( ) => {
129- await page . getByLabel ( 'Name' , { exact : true } ) . fill ( '' ) ;
83+ await locators . export . nameInput ( ) . fill ( '' ) ;
13084 await locators . modal . button ( 'Export' ) . click ( ) ;
13185
13286 await expect ( page . getByText ( 'Name is required' ) ) . toBeVisible ( ) ;
@@ -135,13 +89,24 @@ test.describe('Export Postman Collection - Preserve scripts option', () => {
13589 await expect ( locators . modal . title ( 'Export to Postman' ) ) . toBeVisible ( ) ;
13690 } ) ;
13791
138- // Close both modals to cleanup the app state for the next test
139- await test . step ( 'Close the export and share modals' , async ( ) => {
140- await locators . export . postmanModal ( ) . getByTestId ( 'modal-close-button' ) . click ( ) ;
141- await expect ( locators . modal . title ( 'Export to Postman' ) ) . toBeHidden ( ) ;
142- await locators . modal . byTitle ( 'Share Collection' ) . getByTestId ( 'modal-close-button' ) . click ( ) ;
143- await expect ( locators . modal . title ( 'Share Collection' ) ) . toBeHidden ( ) ;
92+ await closeExportToPostmanModal ( page ) ;
93+ } ) ;
94+
95+ test ( 'should block export when the name has invalid characters' , async ( { pageWithUserData : page } ) => {
96+ const locators = buildCommonLocators ( page ) ;
97+
98+ await openExportToPostmanModal ( page , COLLECTION_NAME ) ;
99+
100+ await test . step ( 'An invalid name shows a validation error and blocks export' , async ( ) => {
101+ await locators . export . nameInput ( ) . fill ( 'foo/bar' ) ;
102+ await locators . modal . button ( 'Export' ) . click ( ) ;
103+
104+ await expect ( page . getByText ( 'Special characters aren\'t allowed in the name' ) ) . toBeVisible ( ) ;
105+ // The modal stays open and the export did not proceed
106+ await expect ( locators . modal . title ( 'Export to Postman' ) ) . toBeVisible ( ) ;
144107 } ) ;
108+
109+ await closeExportToPostmanModal ( page ) ;
145110 } ) ;
146111
147112 test ( 'should let the user rename to avoid overwriting an existing file' , async ( { pageWithUserData : page , createTmpDir } ) => {
@@ -151,17 +116,17 @@ test.describe('Export Postman Collection - Preserve scripts option', () => {
151116 // Pre-seed a conflicting file for the default (collection) name
152117 fs . writeFileSync ( nodePath . join ( outputDir , `${ COLLECTION_NAME } .json` ) , '{"stale":true}' , 'utf-8' ) ;
153118
154- await openExportToPostmanModal ( page ) ;
119+ await openExportToPostmanModal ( page , COLLECTION_NAME ) ;
155120
156121 await test . step ( 'Exporting over an existing file prompts to replace' , async ( ) => {
157- await page . getByLabel ( 'Location' , { exact : true } ) . fill ( outputDir ) ;
122+ await locators . export . locationInput ( ) . fill ( outputDir ) ;
158123 await locators . modal . button ( 'Export' ) . click ( ) ;
159124 await expect ( page . getByText ( 'Name already exists in this location' ) ) . toBeVisible ( ) ;
160125 await expect ( locators . modal . button ( 'Replace' ) ) . toBeVisible ( ) ;
161126 } ) ;
162127
163128 await test . step ( 'Renaming clears the conflict and restores Export' , async ( ) => {
164- await page . getByLabel ( 'Name' , { exact : true } ) . fill ( 'Renamed Export' ) ;
129+ await locators . export . nameInput ( ) . fill ( 'Renamed Export' ) ;
165130 await expect ( page . getByText ( 'Name already exists in this location' ) ) . toBeHidden ( ) ;
166131 await expect ( locators . modal . button ( 'Export' ) ) . toBeVisible ( ) ;
167132 } ) ;
0 commit comments