@@ -71,8 +71,13 @@ function buildRuleSpecFromSchemaRow(row) {
7171function schemaRowsToSpec ( schemaRows ) {
7272 const lines = [ ] ;
7373 ( schemaRows || [ ] ) . forEach ( ( row ) => {
74- lines . push ( String ( row ?. name ?? '' ) . trim ( ) ) ;
75- lines . push ( buildRuleSpecFromSchemaRow ( row ) ) ;
74+ const name = String ( row ?. name ?? '' ) . trim ( ) ;
75+ const ruleSpec = buildRuleSpecFromSchemaRow ( row ) ;
76+ if ( name . length === 0 && ruleSpec . length === 0 ) {
77+ return ;
78+ }
79+ lines . push ( name ) ;
80+ lines . push ( ruleSpec ) ;
7681 } ) ;
7782 return lines . join ( '\n' ) ;
7883}
@@ -227,8 +232,28 @@ class DataGeneratorPage {
227232 <label>Output Format
228233 <select id="generatorOutputFormat"></select>
229234 </label>
230- <button id="generateDataButton">Generate Data</button>
231- <button id="generateAllPairsButton" style="display:none;">Generate Pairwise</button>
235+ <span class="generator-button-with-help">
236+ <span
237+ class="helpicon"
238+ data-help="generator-generate-data-help"
239+ data-help-text='
240+ <p>Generate Data for currently defined rows and output format to file.</p>
241+ <p><a class="helplink" href="https://anywaydata.com/docs/test-data/generate-to-file" target="_blank" rel="noopener noreferrer">Generate To File docs</a></p>
242+ '
243+ ></span>
244+ <button id="generateDataButton"><span class="generator-file-icon" aria-hidden="true"></span>Generate Data</button>
245+ </span>
246+ <span class="generator-button-with-help" id="generateAllPairsButtonWrapper" style="display:none;">
247+ <span
248+ class="helpicon"
249+ data-help="generator-pairwise-help"
250+ data-help-text='
251+ <p>Generate Pairwise Data from schema to a file.</p>
252+ <p><a class="helplink" href="https://anywaydata.com/docs/test-data/pairwise-testing" target="_blank" rel="noopener noreferrer">Pairwise testing docs</a></p>
253+ '
254+ ></span>
255+ <button id="generateAllPairsButton"><span class="generator-file-icon" aria-hidden="true"></span>Generate Pairwise</button>
256+ </span>
232257 <div class="generator-options-wrapper">
233258 <div id="generatorOptionsPanel" class="generator-options-panel"></div>
234259 <div id="generatorStatusText" class="generator-status-text" aria-live="polite" role="status"></div>
@@ -242,7 +267,16 @@ class DataGeneratorPage {
242267 <div class="generator-preview-controls" id="generatorPreviewControlsSection" data-subsection-order="1" aria-label="Preview Controls">
243268 <label for="previewRowsCount" class="generator-preview-count-label">Preview Items Count</label>
244269 <input type="number" id="previewRowsCount" min="0" max="50" value="10">
245- <button id="previewDataButton">Preview</button>
270+ <span class="generator-button-with-help">
271+ <span
272+ class="helpicon"
273+ data-help="generator-preview-help"
274+ data-help-text='
275+ <p>Show a preview of the defined items count in the Output Preview area.</p>
276+ '
277+ ></span>
278+ <button id="previewDataButton">Preview</button>
279+ </span>
246280 </div>
247281 <div class="generator-output-preview" id="generatorOutputPreviewSection" data-subsection-order="2" aria-label="Output Preview">
248282 <label for="generatorOutputPreview">Output Preview</label>
@@ -349,6 +383,10 @@ class DataGeneratorPage {
349383
350384 const schemaModeToggleButton = this . documentObj . getElementById ( 'schemaModeToggleButton' ) ;
351385 schemaModeToggleButton . addEventListener ( 'click' , ( ) => this . toggleSchemaEditMode ( ) ) ;
386+ const schemaTextArea = this . documentObj . getElementById ( 'generatorSchemaText' ) ;
387+ schemaTextArea ?. addEventListener ( 'input' , ( ) => {
388+ this . updateAllPairsButtonVisibility ( ) ;
389+ } ) ;
352390
353391 const previewDataButton = this . documentObj . getElementById ( 'previewDataButton' ) ;
354392 previewDataButton . addEventListener ( 'click' , ( ) => this . previewData ( ) ) ;
@@ -610,6 +648,26 @@ class DataGeneratorPage {
610648 return { rows, errors : [ ] } ;
611649 }
612650
651+ syncSchemaRowsFromTextMode ( { showErrors = false } = { } ) {
652+ if ( ! this . isTextMode ) {
653+ return { rows : this . schemaRows , errors : [ ] } ;
654+ }
655+
656+ const textArea = this . documentObj . getElementById ( 'generatorSchemaText' ) ;
657+ const parsed = this . parseSchemaTextToRows ( textArea ?. value || '' ) ;
658+ if ( parsed . errors . length > 0 ) {
659+ if ( showErrors ) {
660+ this . alertFn ( parsed . errors . join ( '\n' ) ) ;
661+ }
662+ return parsed ;
663+ }
664+
665+ // Keep empty text schemas as zero rows while in text mode so validation can
666+ // report "Add at least one schema row." instead of introducing a synthetic blank row.
667+ this . schemaRows = parsed . rows ;
668+ return { rows : this . schemaRows , errors : [ ] } ;
669+ }
670+
613671 ruleToSchemaRow ( rule ) {
614672 const row = this . createBlankSchemaRow ( ) ;
615673 row . name = String ( rule ?. name ?? '' ) ;
@@ -847,7 +905,12 @@ class DataGeneratorPage {
847905 }
848906
849907 createConfiguredGenerator ( ) {
850- const { errors, rows } = validateSchemaRows ( this . schemaRows ) ;
908+ const parsed = this . syncSchemaRowsFromTextMode ( { showErrors : false } ) ;
909+ if ( parsed . errors ?. length > 0 ) {
910+ return { errors : parsed . errors } ;
911+ }
912+
913+ const { errors, rows } = validateSchemaRows ( parsed . rows ) ;
851914 if ( errors . length > 0 ) {
852915 return { errors } ;
853916 }
@@ -1025,7 +1088,12 @@ class DataGeneratorPage {
10251088 }
10261089
10271090 countEnumColumns ( ) {
1028- const { errors, rows } = validateSchemaRows ( this . schemaRows ) ;
1091+ const parsed = this . syncSchemaRowsFromTextMode ( { showErrors : false } ) ;
1092+ if ( parsed . errors ?. length > 0 ) {
1093+ return 0 ;
1094+ }
1095+
1096+ const { errors, rows } = validateSchemaRows ( parsed . rows ) ;
10291097 if ( errors . length > 0 ) {
10301098 return 0 ;
10311099 }
@@ -1066,9 +1134,9 @@ class DataGeneratorPage {
10661134
10671135 updateAllPairsButtonVisibility ( ) {
10681136 const enumCount = this . countEnumColumns ( ) ;
1069- const button = this . documentObj . getElementById ( 'generateAllPairsButton ' ) ;
1070- if ( button ) {
1071- button . style . display = enumCount >= 2 ? '' : 'none' ;
1137+ const buttonWrapper = this . documentObj . getElementById ( 'generateAllPairsButtonWrapper ' ) ;
1138+ if ( buttonWrapper ) {
1139+ buttonWrapper . style . display = enumCount >= 2 ? 'inline-flex ' : 'none' ;
10721140 }
10731141 }
10741142
0 commit comments