Jira Test Management

Search Test Steps in Jira: JQL Limits and Xray Cloud Workarounds

Search Test Steps in Jira: JQL Limits and Xray Cloud Workarounds

A refund rule changes, and QA needs to find every manual test that mentions the old behavior. Searching issue summaries finds some cases, but the wording may appear only in a step action, a data cell, or an expected result. A missing search result does not establish that the test library contains no references.

For Xray Cloud, use a three-part approach: filter candidate Jira issues, retrieve their structured test definitions through a bounded getTests query, then match the returned step text locally. Each part has a different scope. Native Jira filtering selects issues; it does not become a manual-step text index because the selected issues are Tests.

Table of Contents

Separate Jira Candidate Filters From Step Text

Jira Query Language, or JQL, searches the fields and search functions available in the Jira configuration. Native text searches operate on supported Jira fields. Xray Cloud exposes manual step definitions separately through its API, including action, data, and result. Do not assume that text visible in an app panel is indexed by Jira's native text search.

For example, project = QA AND issuetype = Test describes a candidate issue set, not a search inside those issues' manual steps. QA and Test are illustrative names. Use the actual configured project and Xray Test issue-type names or IDs in your site. Adding a text condition that searches an issue's summary or description can exclude a genuine step match when the term appears nowhere in those issue fields.

The distinction also applies to expected results. The Step field named result describes the expected behavior in a reusable test specification. It is not the observed outcome of an execution attempt. Searching it will not find every failed run or every tester's actual-result comment. Consistent separation of actions, inputs, and expectations makes findings easier to interpret; the Jira test case template explains that authoring structure.

Installed apps may provide additional search functions or indexes, but those need their own product and deployment verification. Do not invent a Scenario field, reuse an old Data Center function in Cloud, or apply advice for another testing app. The procedure below relies on the documented Xray Cloud retrieval fields rather than an assumed search extension.

Define a Finite Search Scope Before Retrieval

Start with an authorized read-only task and a defined population, such as the Xray Test issues maintained by a particular project team. Confirm that Xray Cloud is installed, that the account has the necessary Jira and Xray access, and that the configured issue type identifies the intended Tests. This is an app-specific procedure, not a native Jira feature or a Server/Data Center recipe.

Have the administrator confirm the approved authentication setup and regional endpoint. Xray documents authentication based on an API key associated with a user, using a Client ID and Client Secret to obtain a token. Keep those values and tokens in approved secret handling, never in a test-search report. No credentials are needed to understand the example here.

There is an important documentation caveat: Xray's GraphQL overview and its region table show inconsistent endpoint paths and hyperlink destinations. Confirm the endpoint for your deployment through the administrator or vendor before configuring a client. Do not guess a regional URL by substituting a hostname or removing a path segment.

Save the Candidate Manifest

Obtain the candidate issues through your organization's approved read-only Jira search or export process. Save a manifest mapping each issue ID to its key, together with the exact parent filter, account reference, and acquisition time. If that search has multiple pages, finish and reconcile them before calling the candidate population complete.

Use a finite list of distinct candidate keys to define disjoint retrieval partitions. An illustrative partition might use project = QA AND issuetype = Test AND key IN (QA-101, QA-102, QA-103). Every key belongs to one partition, and the union of partition keys must equal the saved manifest. These are fictional keys, not a query against a real site.

This makes the Xray limit manageable without assuming that project, component, or label categories are exhaustive. Those fields can help define the parent population when they reflect the task, but overlapping labels are not automatically disjoint partitions. A narrower filter also changes the claim: searching one component cannot establish that the entire project has no matching step.

Keep each partition's JQL within 100 matching issues. The current getTests reference says that a JQL returning more than 100 issues produces an error asking the caller to refine the search. A request limit of 100 or a later start offset does not remove that condition. If the JQL is too broad, refine the partition before continuing.

Retrieve Complete Bounded getTests Results

A minimal retrieval needs test identity, test type, manual steps, and pagination metadata. The following single-line GraphQL query is an unexecuted template, not a tenant-tested integration. It selects only the fields needed for this procedure:

query SearchSteps($jql: String!, $start: Int!) { getTests(jql: $jql, start: $start, limit: 50) { total start limit warnings results { issueId testType { name kind } steps { id action data result } } } }

Supply the approved partition filter as the jql variable and begin with start equal to zero. The limit of 50 is an illustrative page size, not an instruction to stop after the first page. The documented limit range is 1 to 100; the separate JQL matching cap still applies. Use the manifest's issue-ID-to-key mapping when reporting findings.

The response container provides total, start, limit, results, and warnings. Preserve the request variables and complete response for each page before retrieving another. Store a safe account reference and retrieval timestamps, but exclude authentication headers and tokens from these records. A result summary without its scope metadata cannot explain which cases were searched.

Reconcile Pages Before Declaring Completion

Use the following checks as a local retrieval policy, not as a claim that the API guarantees a frozen dataset:

  1. Check the transport outcome and the GraphQL response body. Reject errors even when data is also present. GraphQL can return partial data alongside field errors, so an HTTP success alone is insufficient.
  2. Require the requested start offset and valid total, limit, and results values. For an eligible partition needing another page, request the next offset after the rows actually received. Do not skip a missing page or treat a null results container as an empty success.
  3. Track distinct issue IDs across pages. Reject duplicates and unexplained total changes. An unexpectedly empty intermediate page, missing identity, or warning about an invalid Test requires investigation rather than a completeness flag.
  4. Compare the final distinct returned IDs with the partition's expected IDs, then compare the completed partition union with the parent manifest. A plausible total is weaker evidence than agreement on the actual identities.
  5. Investigate permission differences, removed cases, changed types, or concurrent edits when the sets disagree. Record the incomplete scope and repeat only the affected read-only retrieval after resolving its cause.

Offset pagination does not supply a remote snapshot guarantee. A library can change between requests even when totals remain equal. Retain the retrieval interval and any modification information available through the approved workflow; use a controlled review window when the decision needs a stable baseline. Count reconciliation can detect some drift, but cannot prove that no step text changed during the scan.

Match the Returned Manual Fields With Explicit Rules

Choose matching semantics before reviewing results. A useful starting policy is a nonempty literal substring comparison after Unicode case folding, performed independently within action, data, and result. Preserve the original strings for display. This finds Refund and REFUND, but does not perform stemming, regular expressions, fuzzy matching, or Jira's indexed text-search processing.

Do not join neighboring fields before comparison. If an action ends with ref and its data starts with und, that does not create a refund match under this policy. Likewise, do not silently strip markup, normalize whitespace, or translate text. Such transformations can be useful, but they define a different search and should be recorded as a separate pass.

For an expected-result-only task, restrict the comparison to result and say so in the report. For a broader wording review, inspect all three fields and identify each matching field separately. A case-level yes/no flag hides whether the relevant phrase occurs in an instruction, an input value, or an expectation.

Separate Manual Steps From Other Definitions

Use testType.kind to distinguish definition formats. Xray documents Steps, Gherkin, and Unstructured kinds; the displayed testType.name is a separate value. Process the Steps-format definitions for this manual-step task. Keep Gherkin and Unstructured tests in separate counts rather than searching them as if they had action/data/result rows.

Handle empty data deliberately:

  • A null field has no string to compare. Record it separately from an empty string, which is present but contains no characters.
  • An empty manual steps array contains no returned rows. A null array or missing requested field needs investigation before claiming that a manual definition was fully inspected.
  • An unknown or missing test type is an unresolved classification, not a manual test with no matches.

The field scope is also narrower than every possible Xray artifact. Attachments, custom step fields, datasets, called-test definitions, library expansions, Gherkin text, and execution results are not automatically searched by this query. A reference to another test does not prove its contents were expanded. Add separately documented retrieval and completeness rules if those artifacts are part of the task.

For each hit, retain the Jira key, issue ID, step ID, matched field, original text context, and one-based position in the returned steps array. That position helps a reviewer locate the observation, but is not a stable identity or a promise about UI numbering after edits. Keep the step ID and retrieval context even when a readable position is available.

A Fictional Refund Search With Field-Level Findings

Assume a saved candidate manifest contains QA-101, QA-102, and QA-103. An authored synthetic response-shaped fixture assigns the first two Tests to the Steps kind and the third to Gherkin. These are invented cases for explanation, not responses retrieved from Jira or Xray.

Apply the literal case-folded term refund to the three returned manual steps below. Response positions are one-based within each Test's steps array. The table shows the text relevant to understanding the comparison, not a complete API response.

Fictional Test and Step

Returned Field Text

Local Match for Refund

QA-101, step s-a, response position 1

action: Submit a refund

action

QA-101, step s-b, response position 2

data: REFUND-ONLY; result: Refund is rejected

data and result

QA-102, step s-c, response position 1

action: Open account; data: empty string; result: Balance unchanged

No selected-field match

The local comparison finds three matching fields across two steps in one manual test. The other manual test has no selected-field match. QA-103 is classified separately as Gherkin and is not searched by this manual-field comparison. Its presence in the candidate manifest does not turn it into another inspected manual case.

In the synthetic fixture, the first step's data is null and the last step's data is an empty string. Neither produces a match, but they remain different observations in the scope record. The omitted fields in the table still exist in the fixture; table abbreviation is not a recommendation to ignore missing fields in a real response.

A reviewer can now distinguish QA-101's action hit from the data and expected-result hits in its next step. An expected-result-only pass would retain the result hit and exclude the action and data hits. That narrower result says nothing about phrases in attachments, BDD definitions, or actual execution notes.

Report Matches and Incomplete Searches Differently

A useful search report begins with the question and its boundary: which manifest was searched, which principal's access was used, when retrieval occurred, which partitions completed, and which fields and matching rules were applied. Attach the field-level findings and a separate exceptions list. Describe permissions as a visibility boundary, not as proof that inaccessible tests do not exist.

Keep the follow-up read-only until someone reviews each finding. A matching expected result may describe behavior that is still correct, while a match in a data identifier may need no change at all. Finding text does not authorize bulk edits, test execution, or modification of earlier run evidence.

Reserve no match within the completed scope for a reconciled retrieval with no matching selected strings. If a page failed, a warning remains unresolved, or an expected issue is missing, report an incomplete search instead. Even a completed scan is bounded by its manifest, access, fields, matching policy, and retrieval interval. Start with a known finite set, make those boundaries visible, and trust a negative finding only after the retrieval evidence supports it.

Related

More on Jira Test Management

Create traceable test cases, prepare release-specific test runs, and keep approved coverage current as the product changes.