webpipe-js 2.0.20 → 2.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -367,7 +367,7 @@ var Parser = class {
367
367
  if (this.cur() === ")") {
368
368
  throw new ParseFailure("empty tag arguments not allowed", this.pos);
369
369
  }
370
- args.push(this.parseIdentifier());
370
+ args.push(this.parseTagArgument());
371
371
  this.skipInlineSpaces();
372
372
  while (this.cur() === ",") {
373
373
  this.pos++;
@@ -375,12 +375,17 @@ var Parser = class {
375
375
  if (this.cur() === ")") {
376
376
  throw new ParseFailure("trailing comma in tag arguments", this.pos);
377
377
  }
378
- args.push(this.parseIdentifier());
378
+ args.push(this.parseTagArgument());
379
379
  this.skipInlineSpaces();
380
380
  }
381
381
  this.expect(")");
382
382
  return args;
383
383
  }
384
+ parseTagArgument() {
385
+ const bt = this.tryParse(() => this.parseBacktickString());
386
+ if (bt !== null) return bt;
387
+ return this.parseIdentifier();
388
+ }
384
389
  parseTags() {
385
390
  const tags = [];
386
391
  while (!this.eof()) {
@@ -912,6 +917,85 @@ var Parser = class {
912
917
  callTarget
913
918
  };
914
919
  }
920
+ if (field === "selector") {
921
+ const selectorStr = (() => {
922
+ const bt = this.tryParse(() => this.parseBacktickString());
923
+ if (bt !== null) return bt;
924
+ const qt = this.tryParse(() => this.parseQuotedString());
925
+ if (qt !== null) return qt;
926
+ throw new Error("selector requires quoted string");
927
+ })();
928
+ this.skipInlineSpaces();
929
+ const operation = this.consumeWhile((c) => c !== " " && c !== "\n");
930
+ this.skipInlineSpaces();
931
+ let domAssert;
932
+ let comparison2;
933
+ let value2;
934
+ if (operation === "exists") {
935
+ domAssert = { kind: "Exists" };
936
+ comparison2 = "exists";
937
+ value2 = "true";
938
+ } else if (operation === "does") {
939
+ this.expect("not");
940
+ this.skipInlineSpaces();
941
+ this.expect("exist");
942
+ domAssert = { kind: "Exists" };
943
+ comparison2 = "does_not_exist";
944
+ value2 = "false";
945
+ } else if (operation === "text") {
946
+ domAssert = { kind: "Text" };
947
+ this.skipInlineSpaces();
948
+ comparison2 = this.consumeWhile((c) => c !== " " && c !== "\n");
949
+ this.skipInlineSpaces();
950
+ value2 = (() => {
951
+ const v1 = this.tryParse(() => this.parseBacktickString());
952
+ if (v1 !== null) return v1;
953
+ const v2 = this.tryParse(() => this.parseQuotedString());
954
+ if (v2 !== null) return v2;
955
+ return this.consumeWhile((c) => c !== "\n");
956
+ })();
957
+ } else if (operation === "count") {
958
+ domAssert = { kind: "Count" };
959
+ let compParts = "";
960
+ while (this.pos < this.text.length && this.text[this.pos] !== "\n") {
961
+ const c = this.text[this.pos];
962
+ if (/\d/.test(c)) break;
963
+ compParts += c;
964
+ this.pos++;
965
+ }
966
+ comparison2 = compParts.trim();
967
+ value2 = this.consumeWhile((c) => c !== "\n").trim();
968
+ } else if (operation === "attribute") {
969
+ const attrName = (() => {
970
+ const bt = this.tryParse(() => this.parseBacktickString());
971
+ if (bt !== null) return bt;
972
+ const qt = this.tryParse(() => this.parseQuotedString());
973
+ if (qt !== null) return qt;
974
+ throw new Error("attribute requires quoted name");
975
+ })();
976
+ this.skipInlineSpaces();
977
+ comparison2 = this.consumeWhile((c) => c !== " " && c !== "\n");
978
+ this.skipInlineSpaces();
979
+ value2 = (() => {
980
+ const v1 = this.tryParse(() => this.parseBacktickString());
981
+ if (v1 !== null) return v1;
982
+ const v2 = this.tryParse(() => this.parseQuotedString());
983
+ if (v2 !== null) return v2;
984
+ return this.consumeWhile((c) => c !== "\n");
985
+ })();
986
+ domAssert = { kind: "Attribute", name: attrName };
987
+ } else {
988
+ throw new Error(`Unknown selector operation: ${operation}`);
989
+ }
990
+ return {
991
+ conditionType: ct,
992
+ field: "selector",
993
+ comparison: comparison2,
994
+ value: value2,
995
+ selector: selectorStr,
996
+ domAssert
997
+ };
998
+ }
915
999
  let headerName;
916
1000
  if (field === "header") {
917
1001
  const h1 = this.tryParse(() => this.parseBacktickString());
@@ -1194,6 +1278,24 @@ function printMock(mock, indent = " ") {
1194
1278
  }
1195
1279
  function printCondition(condition, indent = " ") {
1196
1280
  const condType = condition.conditionType.toLowerCase();
1281
+ if (condition.field === "selector" && condition.selector && condition.domAssert) {
1282
+ const selector = condition.selector;
1283
+ const formatValue = (val) => {
1284
+ if (val.startsWith("`") || val.startsWith('"')) return val;
1285
+ if (val.includes("\n") || val.includes("{") || val.includes("[")) return `\`${val}\``;
1286
+ return `"${val}"`;
1287
+ };
1288
+ if (condition.domAssert.kind === "Exists") {
1289
+ const operation = condition.comparison === "exists" ? "exists" : "does not exist";
1290
+ return `${indent}${condType} selector "${selector}" ${operation}`;
1291
+ } else if (condition.domAssert.kind === "Text") {
1292
+ return `${indent}${condType} selector "${selector}" text ${condition.comparison} ${formatValue(condition.value)}`;
1293
+ } else if (condition.domAssert.kind === "Count") {
1294
+ return `${indent}${condType} selector "${selector}" count ${condition.comparison} ${condition.value}`;
1295
+ } else if (condition.domAssert.kind === "Attribute") {
1296
+ return `${indent}${condType} selector "${selector}" attribute "${condition.domAssert.name}" ${condition.comparison} ${formatValue(condition.value)}`;
1297
+ }
1298
+ }
1197
1299
  const fieldPart = condition.headerName ? `${condition.field} "${condition.headerName}"` : condition.jqExpr ? `${condition.field} \`${condition.jqExpr}\`` : condition.field;
1198
1300
  const value = condition.value.startsWith("`") ? condition.value : condition.value.includes("\n") || condition.value.includes("{") || condition.value.includes("[") ? `\`${condition.value}\`` : condition.value;
1199
1301
  return `${indent}${condType} ${fieldPart} ${condition.comparison} ${value}`;
@@ -1406,7 +1508,13 @@ function formatTags(tags) {
1406
1508
  }
1407
1509
  function formatTag(tag) {
1408
1510
  const negation = tag.negated ? "!" : "";
1409
- const args = tag.args.length > 0 ? `(${tag.args.join(",")})` : "";
1511
+ const formattedArgs = tag.args.map((arg) => {
1512
+ if (/[^a-zA-Z0-9_-]/.test(arg)) {
1513
+ return `\`${arg}\``;
1514
+ }
1515
+ return arg;
1516
+ });
1517
+ const args = tag.args.length > 0 ? `(${formattedArgs.join(",")})` : "";
1410
1518
  return `@${negation}${tag.name}${args}`;
1411
1519
  }
1412
1520
  function formatTagExpr(expr) {
package/dist/index.d.cts CHANGED
@@ -180,6 +180,16 @@ type When = {
180
180
  varType: string;
181
181
  name: string;
182
182
  };
183
+ type DomAssertType = {
184
+ kind: 'Exists';
185
+ } | {
186
+ kind: 'Text';
187
+ } | {
188
+ kind: 'Count';
189
+ } | {
190
+ kind: 'Attribute';
191
+ name: string;
192
+ };
183
193
  interface Condition {
184
194
  conditionType: 'Then' | 'And';
185
195
  field: string;
@@ -189,6 +199,8 @@ interface Condition {
189
199
  value: string;
190
200
  isCallAssertion?: boolean;
191
201
  callTarget?: string;
202
+ selector?: string;
203
+ domAssert?: DomAssertType;
192
204
  }
193
205
  type DiagnosticSeverity = 'error' | 'warning' | 'info';
194
206
  interface ParseDiagnostic {
@@ -232,4 +244,4 @@ declare function formatTagExpr(expr: TagExpr): string;
232
244
  declare function formatPipelineRef(ref: PipelineRef): string[];
233
245
  declare function formatWhen(when: When): string;
234
246
 
235
- export { type Comment, type Condition, type Config, type ConfigProperty, type ConfigType, type ConfigValue, type Describe, type DiagnosticSeverity, type DispatchBranch, type GraphQLSchema, type It, type Mock, type MutationResolver, type NamedPipeline, type ParseDiagnostic, type Pipeline, type PipelineRef, type PipelineStep, type Program, type QueryResolver, type ResultBranch, type ResultBranchType, type Route, type Tag, type TagExpr, type Variable, type When, formatConfigValue, formatPipelineRef, formatPipelineStep, formatStepConfig, formatTag, formatTagExpr, formatTags, formatWhen, getPipelineRanges, getVariableRanges, parseProgram, parseProgramWithDiagnostics, prettyPrint, printComment, printCondition, printConfig, printDescribe, printGraphQLSchema, printMock, printMutationResolver, printPipeline, printQueryResolver, printRoute, printTest, printVariable };
247
+ export { type Comment, type Condition, type Config, type ConfigProperty, type ConfigType, type ConfigValue, type Describe, type DiagnosticSeverity, type DispatchBranch, type DomAssertType, type GraphQLSchema, type It, type Mock, type MutationResolver, type NamedPipeline, type ParseDiagnostic, type Pipeline, type PipelineRef, type PipelineStep, type Program, type QueryResolver, type ResultBranch, type ResultBranchType, type Route, type Tag, type TagExpr, type Variable, type When, formatConfigValue, formatPipelineRef, formatPipelineStep, formatStepConfig, formatTag, formatTagExpr, formatTags, formatWhen, getPipelineRanges, getVariableRanges, parseProgram, parseProgramWithDiagnostics, prettyPrint, printComment, printCondition, printConfig, printDescribe, printGraphQLSchema, printMock, printMutationResolver, printPipeline, printQueryResolver, printRoute, printTest, printVariable };
package/dist/index.d.ts CHANGED
@@ -180,6 +180,16 @@ type When = {
180
180
  varType: string;
181
181
  name: string;
182
182
  };
183
+ type DomAssertType = {
184
+ kind: 'Exists';
185
+ } | {
186
+ kind: 'Text';
187
+ } | {
188
+ kind: 'Count';
189
+ } | {
190
+ kind: 'Attribute';
191
+ name: string;
192
+ };
183
193
  interface Condition {
184
194
  conditionType: 'Then' | 'And';
185
195
  field: string;
@@ -189,6 +199,8 @@ interface Condition {
189
199
  value: string;
190
200
  isCallAssertion?: boolean;
191
201
  callTarget?: string;
202
+ selector?: string;
203
+ domAssert?: DomAssertType;
192
204
  }
193
205
  type DiagnosticSeverity = 'error' | 'warning' | 'info';
194
206
  interface ParseDiagnostic {
@@ -232,4 +244,4 @@ declare function formatTagExpr(expr: TagExpr): string;
232
244
  declare function formatPipelineRef(ref: PipelineRef): string[];
233
245
  declare function formatWhen(when: When): string;
234
246
 
235
- export { type Comment, type Condition, type Config, type ConfigProperty, type ConfigType, type ConfigValue, type Describe, type DiagnosticSeverity, type DispatchBranch, type GraphQLSchema, type It, type Mock, type MutationResolver, type NamedPipeline, type ParseDiagnostic, type Pipeline, type PipelineRef, type PipelineStep, type Program, type QueryResolver, type ResultBranch, type ResultBranchType, type Route, type Tag, type TagExpr, type Variable, type When, formatConfigValue, formatPipelineRef, formatPipelineStep, formatStepConfig, formatTag, formatTagExpr, formatTags, formatWhen, getPipelineRanges, getVariableRanges, parseProgram, parseProgramWithDiagnostics, prettyPrint, printComment, printCondition, printConfig, printDescribe, printGraphQLSchema, printMock, printMutationResolver, printPipeline, printQueryResolver, printRoute, printTest, printVariable };
247
+ export { type Comment, type Condition, type Config, type ConfigProperty, type ConfigType, type ConfigValue, type Describe, type DiagnosticSeverity, type DispatchBranch, type DomAssertType, type GraphQLSchema, type It, type Mock, type MutationResolver, type NamedPipeline, type ParseDiagnostic, type Pipeline, type PipelineRef, type PipelineStep, type Program, type QueryResolver, type ResultBranch, type ResultBranchType, type Route, type Tag, type TagExpr, type Variable, type When, formatConfigValue, formatPipelineRef, formatPipelineStep, formatStepConfig, formatTag, formatTagExpr, formatTags, formatWhen, getPipelineRanges, getVariableRanges, parseProgram, parseProgramWithDiagnostics, prettyPrint, printComment, printCondition, printConfig, printDescribe, printGraphQLSchema, printMock, printMutationResolver, printPipeline, printQueryResolver, printRoute, printTest, printVariable };
package/dist/index.mjs CHANGED
@@ -317,7 +317,7 @@ var Parser = class {
317
317
  if (this.cur() === ")") {
318
318
  throw new ParseFailure("empty tag arguments not allowed", this.pos);
319
319
  }
320
- args.push(this.parseIdentifier());
320
+ args.push(this.parseTagArgument());
321
321
  this.skipInlineSpaces();
322
322
  while (this.cur() === ",") {
323
323
  this.pos++;
@@ -325,12 +325,17 @@ var Parser = class {
325
325
  if (this.cur() === ")") {
326
326
  throw new ParseFailure("trailing comma in tag arguments", this.pos);
327
327
  }
328
- args.push(this.parseIdentifier());
328
+ args.push(this.parseTagArgument());
329
329
  this.skipInlineSpaces();
330
330
  }
331
331
  this.expect(")");
332
332
  return args;
333
333
  }
334
+ parseTagArgument() {
335
+ const bt = this.tryParse(() => this.parseBacktickString());
336
+ if (bt !== null) return bt;
337
+ return this.parseIdentifier();
338
+ }
334
339
  parseTags() {
335
340
  const tags = [];
336
341
  while (!this.eof()) {
@@ -862,6 +867,85 @@ var Parser = class {
862
867
  callTarget
863
868
  };
864
869
  }
870
+ if (field === "selector") {
871
+ const selectorStr = (() => {
872
+ const bt = this.tryParse(() => this.parseBacktickString());
873
+ if (bt !== null) return bt;
874
+ const qt = this.tryParse(() => this.parseQuotedString());
875
+ if (qt !== null) return qt;
876
+ throw new Error("selector requires quoted string");
877
+ })();
878
+ this.skipInlineSpaces();
879
+ const operation = this.consumeWhile((c) => c !== " " && c !== "\n");
880
+ this.skipInlineSpaces();
881
+ let domAssert;
882
+ let comparison2;
883
+ let value2;
884
+ if (operation === "exists") {
885
+ domAssert = { kind: "Exists" };
886
+ comparison2 = "exists";
887
+ value2 = "true";
888
+ } else if (operation === "does") {
889
+ this.expect("not");
890
+ this.skipInlineSpaces();
891
+ this.expect("exist");
892
+ domAssert = { kind: "Exists" };
893
+ comparison2 = "does_not_exist";
894
+ value2 = "false";
895
+ } else if (operation === "text") {
896
+ domAssert = { kind: "Text" };
897
+ this.skipInlineSpaces();
898
+ comparison2 = this.consumeWhile((c) => c !== " " && c !== "\n");
899
+ this.skipInlineSpaces();
900
+ value2 = (() => {
901
+ const v1 = this.tryParse(() => this.parseBacktickString());
902
+ if (v1 !== null) return v1;
903
+ const v2 = this.tryParse(() => this.parseQuotedString());
904
+ if (v2 !== null) return v2;
905
+ return this.consumeWhile((c) => c !== "\n");
906
+ })();
907
+ } else if (operation === "count") {
908
+ domAssert = { kind: "Count" };
909
+ let compParts = "";
910
+ while (this.pos < this.text.length && this.text[this.pos] !== "\n") {
911
+ const c = this.text[this.pos];
912
+ if (/\d/.test(c)) break;
913
+ compParts += c;
914
+ this.pos++;
915
+ }
916
+ comparison2 = compParts.trim();
917
+ value2 = this.consumeWhile((c) => c !== "\n").trim();
918
+ } else if (operation === "attribute") {
919
+ const attrName = (() => {
920
+ const bt = this.tryParse(() => this.parseBacktickString());
921
+ if (bt !== null) return bt;
922
+ const qt = this.tryParse(() => this.parseQuotedString());
923
+ if (qt !== null) return qt;
924
+ throw new Error("attribute requires quoted name");
925
+ })();
926
+ this.skipInlineSpaces();
927
+ comparison2 = this.consumeWhile((c) => c !== " " && c !== "\n");
928
+ this.skipInlineSpaces();
929
+ value2 = (() => {
930
+ const v1 = this.tryParse(() => this.parseBacktickString());
931
+ if (v1 !== null) return v1;
932
+ const v2 = this.tryParse(() => this.parseQuotedString());
933
+ if (v2 !== null) return v2;
934
+ return this.consumeWhile((c) => c !== "\n");
935
+ })();
936
+ domAssert = { kind: "Attribute", name: attrName };
937
+ } else {
938
+ throw new Error(`Unknown selector operation: ${operation}`);
939
+ }
940
+ return {
941
+ conditionType: ct,
942
+ field: "selector",
943
+ comparison: comparison2,
944
+ value: value2,
945
+ selector: selectorStr,
946
+ domAssert
947
+ };
948
+ }
865
949
  let headerName;
866
950
  if (field === "header") {
867
951
  const h1 = this.tryParse(() => this.parseBacktickString());
@@ -1144,6 +1228,24 @@ function printMock(mock, indent = " ") {
1144
1228
  }
1145
1229
  function printCondition(condition, indent = " ") {
1146
1230
  const condType = condition.conditionType.toLowerCase();
1231
+ if (condition.field === "selector" && condition.selector && condition.domAssert) {
1232
+ const selector = condition.selector;
1233
+ const formatValue = (val) => {
1234
+ if (val.startsWith("`") || val.startsWith('"')) return val;
1235
+ if (val.includes("\n") || val.includes("{") || val.includes("[")) return `\`${val}\``;
1236
+ return `"${val}"`;
1237
+ };
1238
+ if (condition.domAssert.kind === "Exists") {
1239
+ const operation = condition.comparison === "exists" ? "exists" : "does not exist";
1240
+ return `${indent}${condType} selector "${selector}" ${operation}`;
1241
+ } else if (condition.domAssert.kind === "Text") {
1242
+ return `${indent}${condType} selector "${selector}" text ${condition.comparison} ${formatValue(condition.value)}`;
1243
+ } else if (condition.domAssert.kind === "Count") {
1244
+ return `${indent}${condType} selector "${selector}" count ${condition.comparison} ${condition.value}`;
1245
+ } else if (condition.domAssert.kind === "Attribute") {
1246
+ return `${indent}${condType} selector "${selector}" attribute "${condition.domAssert.name}" ${condition.comparison} ${formatValue(condition.value)}`;
1247
+ }
1248
+ }
1147
1249
  const fieldPart = condition.headerName ? `${condition.field} "${condition.headerName}"` : condition.jqExpr ? `${condition.field} \`${condition.jqExpr}\`` : condition.field;
1148
1250
  const value = condition.value.startsWith("`") ? condition.value : condition.value.includes("\n") || condition.value.includes("{") || condition.value.includes("[") ? `\`${condition.value}\`` : condition.value;
1149
1251
  return `${indent}${condType} ${fieldPart} ${condition.comparison} ${value}`;
@@ -1356,7 +1458,13 @@ function formatTags(tags) {
1356
1458
  }
1357
1459
  function formatTag(tag) {
1358
1460
  const negation = tag.negated ? "!" : "";
1359
- const args = tag.args.length > 0 ? `(${tag.args.join(",")})` : "";
1461
+ const formattedArgs = tag.args.map((arg) => {
1462
+ if (/[^a-zA-Z0-9_-]/.test(arg)) {
1463
+ return `\`${arg}\``;
1464
+ }
1465
+ return arg;
1466
+ });
1467
+ const args = tag.args.length > 0 ? `(${formattedArgs.join(",")})` : "";
1360
1468
  return `@${negation}${tag.name}${args}`;
1361
1469
  }
1362
1470
  function formatTagExpr(expr) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webpipe-js",
3
- "version": "2.0.20",
3
+ "version": "2.0.22",
4
4
  "description": "Web Pipe parser",
5
5
  "license": "ISC",
6
6
  "author": "William Cotton",