@mablhq/playwright-tools 2.135.18 → 2.135.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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mablhq-internal/runtime",
3
- "version": "2.135.18",
3
+ "version": "2.135.22",
4
4
  "main": "./index.js",
5
5
  "types": "./index.d.ts"
6
6
  }
@@ -1265,7 +1265,25 @@ class AgenticGenerationRunner {
1265
1265
  }
1266
1266
  return result;
1267
1267
  }
1268
+ userAuthoredObjective() {
1269
+ if (this.config.objectiveIsUserAuthored) {
1270
+ const locked = this.config.testIntent?.trim();
1271
+ if (locked) {
1272
+ return { summary: locked, source: mablApi_1.TestObjectiveSource.User };
1273
+ }
1274
+ }
1275
+ const existing = this.config.existingTest?.objective;
1276
+ if (existing?.source === mablApi_1.TestObjectiveSource.User &&
1277
+ existing.summary?.trim()) {
1278
+ return existing;
1279
+ }
1280
+ return undefined;
1281
+ }
1268
1282
  async resolveTestObjective(summaryStepList, testDescription) {
1283
+ const userAuthored = this.userAuthoredObjective();
1284
+ if (userAuthored) {
1285
+ return userAuthored;
1286
+ }
1269
1287
  try {
1270
1288
  const { summary } = await this.config.apiClient.generateTestSummary(this.config.workspaceId, { fullStepList: summaryStepList, description: testDescription });
1271
1289
  const trimmed = summary?.trim();
@@ -1 +1 @@
1
- {"version":3,"file":"authoringGuideResources.d.ts","sourceRoot":"","sources":["../../src/mabl-authoring/authoringGuideResources.ts"],"names":[],"mappings":"AAcA,OAAO,EAAC,sBAAsB,EAAC,MAAM,SAAS,CAAC;AAwuC/C,qBAAa,uBAAuB;IAClC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,sBAAsB,GAAG,SAAS;IAIxD,IAAI,IAAI,aAAa,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAC,CAAC;CAG1D"}
1
+ {"version":3,"file":"authoringGuideResources.d.ts","sourceRoot":"","sources":["../../src/mabl-authoring/authoringGuideResources.ts"],"names":[],"mappings":"AAcA,OAAO,EAAC,sBAAsB,EAAC,MAAM,SAAS,CAAC;AA4uC/C,qBAAa,uBAAuB;IAClC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,sBAAsB,GAAG,SAAS;IAIxD,IAAI,IAAI,aAAa,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAC,CAAC;CAG1D"}
@@ -560,8 +560,12 @@ find calls.
560
560
  ## \`description\`
561
561
 
562
562
  A natural-language statement of what the element *is*, what it *does*,
563
- and (optionally) how it looks or where it sits on the page. Drives the
564
- description-driven visual resolver when the locator fails.
563
+ and (optionally) how it looks or where it sits on the page. With a
564
+ \`locator\`, it grounds the visual fallback when the locator fails. Without
565
+ one, it is a visual-primary find, which is the right tool for elements with
566
+ no persistent attributes: canvas content, chart points, map pins, SVG nodes,
567
+ unlabeled icon buttons. When the element has an accessible name, a test id,
568
+ or a stable id or role, pair the description with a \`locator\`.
565
569
 
566
570
  Combine purpose with whatever stable cues — color, position, layout,
567
571
  nearby text — actually help find the element. Visual descriptors are
@@ -32,6 +32,9 @@ export declare const propertyComparatorEnum: z.ZodEnum<{
32
32
  contains: "contains";
33
33
  equals: "equals";
34
34
  }>;
35
+ export declare const PRIMARY_FIND_METHOD_NATIVE_ATTRIBUTES = "1";
36
+ export declare const PRIMARY_FIND_METHOD_ELEMENT_DESCRIPTION = "2";
37
+ export declare const PRIMARY_FIND_METHOD_XPATH_ONLY = "3";
35
38
  export declare const primaryFindMethodEnum: z.ZodEnum<{
36
39
  1: "1";
37
40
  2: "2";
@@ -1 +1 @@
1
- {"version":3,"file":"find-descriptors.d.ts","sourceRoot":"","sources":["../../../src/validator/schemas/find-descriptors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"find-descriptors.d.ts","sourceRoot":"","sources":["../../../src/validator/schemas/find-descriptors.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.mobileFindDescriptorSchema = exports.webViewFindElementDescriptorSchema = exports.mobileFindCustomDescriptorSchema = exports.mobileFindElementDescriptorSchema = exports.findDescriptorSchema = exports.findTabDescriptorSchema = exports.findEmailDescriptorSchema = exports.findCookieDescriptorSchema = exports.browserFindAuthoringSchema = exports.findCustomDescriptorSchema = exports.findElementDescriptorSchema = exports.browserFindDescriptorSchema = exports.browserFindTargetSchema = exports.cookieSelectorSchema = exports.mobileFindSpecificationSchema = exports.mobileElementSelectorSchema = exports.normalizedFindDescriptorSchema = exports.mobileFindOptionsSchema = exports.findOptionsSchema = exports.customCssSelectorSchema = exports.customXpathSelectorSchema = exports.simpleElementSelectorSchema = exports.primaryFindMethodEnum = exports.propertyComparatorEnum = exports.elementExpectationEnum = exports.confidenceLevelEnum = exports.NON_ELEMENT_FIND_TYPES = exports.ELEMENT_FIND_TYPES = exports.customFindTypeEnum = exports.findTypeEnum = void 0;
3
+ exports.mobileFindDescriptorSchema = exports.webViewFindElementDescriptorSchema = exports.mobileFindCustomDescriptorSchema = exports.mobileFindElementDescriptorSchema = exports.findDescriptorSchema = exports.findTabDescriptorSchema = exports.findEmailDescriptorSchema = exports.findCookieDescriptorSchema = exports.browserFindAuthoringSchema = exports.findCustomDescriptorSchema = exports.findElementDescriptorSchema = exports.browserFindDescriptorSchema = exports.browserFindTargetSchema = exports.cookieSelectorSchema = exports.mobileFindSpecificationSchema = exports.mobileElementSelectorSchema = exports.normalizedFindDescriptorSchema = exports.mobileFindOptionsSchema = exports.findOptionsSchema = exports.customCssSelectorSchema = exports.customXpathSelectorSchema = exports.simpleElementSelectorSchema = exports.primaryFindMethodEnum = exports.PRIMARY_FIND_METHOD_XPATH_ONLY = exports.PRIMARY_FIND_METHOD_ELEMENT_DESCRIPTION = exports.PRIMARY_FIND_METHOD_NATIVE_ATTRIBUTES = exports.propertyComparatorEnum = exports.elementExpectationEnum = exports.confidenceLevelEnum = exports.NON_ELEMENT_FIND_TYPES = exports.ELEMENT_FIND_TYPES = exports.customFindTypeEnum = exports.findTypeEnum = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const mablscriptFind_1 = require("../../mablscriptFind");
6
6
  const described_union_1 = require("./described-union");
@@ -35,8 +35,15 @@ exports.NON_ELEMENT_FIND_TYPES = new Set([
35
35
  exports.confidenceLevelEnum = zod_1.z.enum(['low', 'medium', 'high', 'unknown']);
36
36
  exports.elementExpectationEnum = zod_1.z.enum(['missing', 'present']);
37
37
  exports.propertyComparatorEnum = zod_1.z.enum(['equals', 'contains']);
38
+ exports.PRIMARY_FIND_METHOD_NATIVE_ATTRIBUTES = '1';
39
+ exports.PRIMARY_FIND_METHOD_ELEMENT_DESCRIPTION = '2';
40
+ exports.PRIMARY_FIND_METHOD_XPATH_ONLY = '3';
38
41
  exports.primaryFindMethodEnum = zod_1.z
39
- .enum(['1', '2', '3'])
42
+ .enum([
43
+ exports.PRIMARY_FIND_METHOD_NATIVE_ATTRIBUTES,
44
+ exports.PRIMARY_FIND_METHOD_ELEMENT_DESCRIPTION,
45
+ exports.PRIMARY_FIND_METHOD_XPATH_ONLY,
46
+ ])
40
47
  .describe('Primary element finding strategy: 1 = native attributes, 2 = element description (AI), 3 = XPath only');
41
48
  const selectorElementAttributeSchema = zod_1.z
42
49
  .object({
@@ -1 +1 @@
1
- {"version":3,"file":"semantic.d.ts","sourceRoot":"","sources":["../../../src/validator/validation/semantic.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAKjB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAC,eAAe,EAAC,MAAM,WAAW,CAAC;AAozB1C,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,OAAO,EACb,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,eAAe,GACvB,gBAAgB,CAqDlB;AAMD,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,EAAE,EAChB,OAAO,EAAE,eAAe,GACvB,gBAAgB,CAqClB"}
1
+ {"version":3,"file":"semantic.d.ts","sourceRoot":"","sources":["../../../src/validator/validation/semantic.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAKjB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAC,eAAe,EAAC,MAAM,WAAW,CAAC;AAm5B1C,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,OAAO,EACb,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,eAAe,GACvB,gBAAgB,CA8DlB;AAMD,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,EAAE,EAChB,OAAO,EAAE,eAAe,GACvB,gBAAgB,CAqClB"}
@@ -96,6 +96,51 @@ function walkForUnwrappedFindTargets(descriptor, path, options) {
96
96
  }
97
97
  return results.length > 0 ? (0, errors_1.mergeResults)(...results) : (0, errors_1.emptyResult)();
98
98
  }
99
+ const LOCATOR_EXPECTED_STEP_TYPES = new Set(['Click', 'EnterText']);
100
+ function getPrimaryFindMethod(find, findTarget) {
101
+ const fromFind = isRecord(find.findOptions)
102
+ ? find.findOptions.primaryFindMethod
103
+ : undefined;
104
+ const fromTarget = isRecord(findTarget.findOptions)
105
+ ? findTarget.findOptions.primaryFindMethod
106
+ : undefined;
107
+ const value = fromFind ?? fromTarget;
108
+ return typeof value === 'string' ? value : undefined;
109
+ }
110
+ function checkDescriptionOnlyFind(descriptor, stepTypeName, path) {
111
+ if (!LOCATOR_EXPECTED_STEP_TYPES.has(stepTypeName)) {
112
+ return (0, errors_1.emptyResult)();
113
+ }
114
+ const find = descriptor.find;
115
+ if (!isRecord(find) || !isRecord(find.findTarget)) {
116
+ return (0, errors_1.emptyResult)();
117
+ }
118
+ if (typeof find.findType === 'string' &&
119
+ find_descriptors_1.NON_ELEMENT_FIND_TYPES.has(find.findType)) {
120
+ return (0, errors_1.emptyResult)();
121
+ }
122
+ const selector = find.findTarget.selector;
123
+ if (!isRecord(selector)) {
124
+ return (0, errors_1.emptyResult)();
125
+ }
126
+ const hasText = (value) => typeof value === 'string' && value.trim().length > 0;
127
+ const describesElement = hasText(selector.description) || hasText(selector.find_prompt);
128
+ if (!describesElement ||
129
+ hasText(selector.locator) ||
130
+ hasText(selector.xpath) ||
131
+ hasText(selector.css_query)) {
132
+ return (0, errors_1.emptyResult)();
133
+ }
134
+ const isDeliberateVisualFind = hasText(selector.find_prompt_prompt_id) ||
135
+ getPrimaryFindMethod(find, find.findTarget) ===
136
+ find_descriptors_1.PRIMARY_FIND_METHOD_ELEMENT_DESCRIPTION;
137
+ if (isDeliberateVisualFind) {
138
+ return (0, errors_1.emptyResult)();
139
+ }
140
+ return (0, errors_1.warningResult)([...path, 'find', 'findTarget', 'selector', 'locator'], 'This find has a `description` and no `locator`, so it resolves as a pure visual find — the visual model matches it from a screenshot on every run. That is the right call for an element with no persistent attributes, but if this one has an accessible name, a test id, or a stable id or role, pair the description with a `locator`.', 'semantic.find_description_only', {
141
+ suggestion: 'Add a `locator` built from the element\'s accessible name or a stable attribute, e.g. `role=button[name="Remove integration"]` or `[data-testid="remove-integration"]`. The locator resolves in milliseconds and the description still grounds the visual fallback.',
142
+ });
143
+ }
99
144
  const SOURCE_EXTRACT_RULES = {
100
145
  url: {
101
146
  label: 'URL',
@@ -371,6 +416,10 @@ function validateStepSemantics(step, stepIndex, options) {
371
416
  if (!findTargetResult.valid || findTargetResult.warnings.length > 0) {
372
417
  resultsToMerge.push(findTargetResult);
373
418
  }
419
+ const descriptionOnlyResult = checkDescriptionOnlyFind(desc, stepTypeName, path);
420
+ if (descriptionOnlyResult.warnings.length > 0) {
421
+ resultsToMerge.push(descriptionOnlyResult);
422
+ }
374
423
  let typeSpecific = (0, errors_1.emptyResult)();
375
424
  if (ASSERT_STEP_TYPES.has(stepTypeName)) {
376
425
  typeSpecific = validateAssertSemantics(desc, path, options);
@@ -385,7 +385,13 @@ async function superviseTunnel(spec, shared) {
385
385
  const tunnelName = spec.configTunnel?.name ?? parsed[CommandArgTunnel];
386
386
  const { apiClient, auth } = await resolveApiClientAndAuth(config, spec.configTunnel, (0, linkAgentUserAgent_1.linkAgentUserAgent)(CLI_VERSION, tunnelName));
387
387
  const { owner, label: requestedLabel } = await resolveOwnerAndLabel(parsed, auth, apiClient, spec.configTunnel, tunnelName);
388
- const announced = await apiClient.announceMablnetLinkAgent(buildAnnounce(parsed, config, owner, requestedLabel, shared.osSettings, shared.carrierHttpProxy, shared.tunnelsOnHost()));
388
+ const announced = await apiClient
389
+ .announceMablnetLinkAgent(buildAnnounce(parsed, config, owner, requestedLabel, shared.osSettings, shared.carrierHttpProxy, shared.tunnelsOnHost()))
390
+ .catch((error) => {
391
+ throw ((owner.type === 'user'
392
+ ? (0, execution_1.describePersonalTunnelDenial)(error, apiClient)
393
+ : undefined) ?? error);
394
+ });
389
395
  try {
390
396
  const label = announced.label ?? requestedLabel;
391
397
  if (!label) {