Back to the journal

engineering / Maintra journal

Maximo regression testing with an AI agent

Plain-English Maximo tests run by an AI agent in a real browser, checked against REST and SQL, then replayed with no model at all. How maxqa works on MAS 9.2.

Graphite and ink drawing of an unattended valve test bench: a blue gate valve clamped in a pressure test stand, two gauges reading the same, a hand pump, and punched paper tape unrolling beside a clipboard.

A patch is going into the test environment on Thursday. Someone has to prove that work orders still approve, purchase orders still receive, PMs still generate and the storeroom still issues. In most Maximo shops that someone opens a spreadsheet of test cases and clicks through them for two days.

The Selenium suite that was meant to do this has not run since the last upgrade. The login page changed, half the locators were generated control ids, and nobody on the team writes Java.

Maximo regression testing with an AI agent works when you split the job. A model reads a screen well and works out which button comes next. It also makes mistakes and reports them as success. So the agent drives the browser, deterministic checks against the database decide the verdict, and the agent is only called back when the recorded run breaks.

Why Maximo resists ordinary test scripts

Generic browser automation assumes a page behaves like a web form. Maximo’s classic UI does not, and most broken test suites I have seen failed on one of these:

Maximo behaviourWhat a generic script doesWhat it needs instead
MAS 9 wraps the classic UI in the manage shell, with the app inside an iframeSearches the top page and finds nothingFind the app frame, fall back to the main frame on 7.6
Control ids such as m6a7dfd2f_tfrow_[C:1]_txt-tb are generatedRecords the id; the next build breaks itTarget by kind and label: the Asset field, the Labor table
Fields only react to real keystrokesSets the value programmatically; Maximo never sees itType key by key, commit with Tab or Enter
A long-poll request is always openWaits for network idle forever, or not at allWait until Maximo’s own event queue is idle
Smart-fill: “matches a number of possible values”Treats it as an errorOpen the lookup and pick the exact match
Some success messages carry E codes, such as BMXAA3280E on a PO status changeFails a passing testRead the message key, not the severity letter

IBM does publish a Maximo Test Automation Framework for validating Manage processes. It is a Java and Selenium script library for out-of-the-box flows, and it has to be adapted to each customer’s configuration and to each MAS release. That suits a team with Java developers. Most Maximo teams I work with have administrators and functional leads instead.

The underlying issue is that Maximo’s business rules surface through a UI event queue, so a test has to go through the screen to exercise them. That is the reason Maintra keeps asset and work rules in backend services behind one API: a test can call the same rule the screen calls.

A test written the way you would brief a tester

A maxqa test is a YAML file with four parts: setup data, plain-language steps, checks, and a recording that is filled in automatically.

name: Approve a new work order via Change Status
app: WOTRACK
tags: [smoke, workorder]
setup:                       # fresh data through REST on every run
  - rest_create:
      os: mxapiwodetail
      data: {siteid: BEDFORD, description: "maxqa approve {{run_id}}", assetnum: "11430"}
      save: {wonum: wonum}
steps: |
  1. Find work order {{wonum}} in the list and open it.
  2. Change its status to Approved (APPR) using the Change Status action.
expect:                      # checked by code, not by the model
  - rest: {os: mxapiwodetail, where: 'wonum="{{wonum}}"', field: status, equals: APPR}
  - sql:  {query: "select status from workorder where wonum='{{wonum}}'", equals: APPR}
  - no_error_messages: true  # no BMXAA....E shown during the run
  - message: BMXAA4591I      # this message must have appeared

Each run creates its own work order through the Maximo REST API, tagged with a run id. Tests never depend on demo data or on the previous run’s leftovers.

maxqa test editor showing a test named Approve a new work order via Change Status: app WOTRACK, three plain-English steps, and checks for a REST status field, no error messages, and an on-screen check.
The same test in maxqa's local web UI. Steps are plain English; the checks underneath decide the verdict. Captured from the MAS 9.2 reference environment.

What the agent actually sees

A screenshot costs thousands of tokens and a small model reads it badly. maxqa’s driver hands the model a compact, numbered list of what a user can act on instead, built from Maximo’s own label conventions:

APP: Work Order Tracking   TAB: Work Order
@e1 field "Work Order" = "1215" [required]
@e2 field "Work Order description" = ""
@e5 field "Asset" = "" [lookup=asset]
@e14 field "Site" = "BEDFORD" [readonly]
@e16 field "Work Type" = "" [lookup=worktype]

Each element carries its kind, label, current value, readonly and required flags, its lookup type, and any field error. When a dialog is open, the list is scoped to the dialog. New BMXAA messages from the status bar are added on top.

The model replies with one JSON action per turn, such as typing 11430 into @e5 and pressing Tab. That keeps the loop identical across an Ollama model, the Claude or Codex command-line tools on a subscription, or an API key.

Where Maximo needs a specific sequence, the driver does it rather than the model.

The clearest example is lookup_select. It opens the Select Value dialog, widens Filter By to ALL and presses Refresh, because Filter By only applies on Refresh and Refresh wipes typed filters. Then it searches with an exact =value filter and clicks the row whose key matches.

A tester learns that order by getting it wrong. The tool now does it in one step.

Application metadata comes straight from the Manage database when a connection is available. The presentation XML gives every label to attribute binding, MAXATTRIBUTE gives types and required flags, and the synonym domains give valid statuses. The agent may run read-only SQL; writes are rejected.

The model never decides the verdict

A test passes only when the agent reports success and every deterministic check passes. The model cannot pass a test on its own say-so.

In the reference environment, a small local model once picked the wrong row in an asset lookup: 11400 instead of 11430. The service request saved and Maximo showed BMXAA4205I, “Record has been saved”. The REST check read assetnum back as 11400 and failed the test. The model flagged the mismatch itself that time, but the verdict did not depend on it noticing; a test that trusted the save message would have passed.

When a test fails, the report explains why in Maximo terms. maxqa reads MAXMESSAGES once from your database and turns each message the run hit into its business key, the values filled into it, and a fix hint.

maxqa run report for a failed Create Labor test: three failed SQL and message checks, two Why lines explaining BMXAA3075W person.CreatePerson and BMXAA8123E system.cannotsave, and the lesson learned from the run.
A failed run from a local 8B model. The checks failed, the Why lines name the real cause, and the run produced a lesson for next time. Captured from the reference environment.

In that Create Labor run, the model typed a new labor code and Maximo replied with BMXAA3075W, asking whether to create a person record. The model treated the question as an error and retyped the value until the loop guard stopped it. maxqa warns after three identical actions and aborts at five.

That principle of AI proposing and evidence deciding is the same one behind Maintra’s AI maintenance assistant, where proposed actions go through approval workflows before anything changes.

Record once, replay with no model

Every passing agent run is saved as semantic steps, never as DOM ids. This is the recording for receiving a purchase order:

replay:
  - op: open_app
    app: receipts
  - op: type
    target: {kind: filter, label: PO, table: POs}
    text: ={{ponum}}
    then: enter
  - op: click
    target: {kind: button, label: Actions, table: Material Receipts}
  - op: click
    target: {kind: option, label: Select Ordered Items}
  - op: click
    target: {kind: button, label: Select All Records, table: Ordered Items}
    in_dialog: Select Ordered Items
  - op: click
    target: {kind: toolbar, label: Save Receipt}

A person can read it, review it in a pull request and fix it by hand. Record numbers are stripped from table names and chosen values become variables, so the recording survives regenerated control ids and fresh data.

Three run modes cover the lifecycle:

ModeWhat runsModel neededUse it for
agentThe agent works through the plain-language stepsYesWriting a test, exploring a flow
replayThe recorded stepsNoFast, repeatable regression
autoReplay first; if it breaks or a check fails, the agent takes over and re-recordsOnly on a breakNightly runs

In the reference environment, a recording with a renamed action broke during replay. In auto mode the local model finished the test from the plain-language steps and saved a new recording.

maxqa Reports screen listing eleven replay runs, all passed, each between 18 and 34 seconds, with zero model calls and zero tokens.
Run history after a replay sweep: every core flow passed with no model calls and no tokens. Captured from the reference environment.

These are the core flows on the MAS 9.2 reference environment, a Manage and DB2 install with IBM’s demo data, written by a local 8B model running on Ollama:

FlowAppModel calls to write itReplay
Plan a work order with labor and materialWOTRACK15No model
Work order lifecycle, APPR to INPRG to COMPWOTRACK14No model
Create and approve a purchase requisitionPR13No model
Create and approve a purchase orderPO15No model
Receive a purchase orderRECEIPTS59 with a larger model, then 8 locallyNo model
Generate a work order from a PMPM8No model
Issue an item to a work orderINVISSUE10No model

The full suite of eleven tests replays unattended in about five minutes, twenty to thirty-five seconds a test. Those figures come from demo data. A heavily customised estate will have its own numbers, so treat them as a record of what the tool did there.

It gets better without retraining

No model weights change. The tool improves through a verified memory stored as plain YAML in the workspace:

  • Lessons. After a troubled run, one reflection call distils general rules, such as setting Site before Asset on a service request. A lesson is shown to the agent for its app, and again the moment its BMXAA code appears on screen.
  • Track record. A lesson starts as a candidate, becomes trusted after two passing runs, and is retired if it keeps not helping. A wrong lesson can cause a failure, never a false pass, because the checks still decide.
  • Teacher and student. A local model is the student. When it fails, a stronger model on a subscription reflects on the failure, the student retries with the new lessons, and if that fails the teacher runs the test itself and compares the two runs.
  • Promotion. Lessons that keep being used are flagged for a developer to build into the driver. Smart-fill handling started as a failure the agent kept hitting; now it is driver code and costs no tokens.

The Create Labor test followed this path. After the reflection lesson, plus a driver change that marks Maximo’s yes or no prompts as questions, the same 8B model passed in six steps. The recording now replays in about twenty seconds.

maxqa Knowledge screen: an estate scan summary with counts of messages, custom objects, restrictions, conditional UI, workflows and escalations; configuration notes for the SR app; an explanation of BMXAA0090E; and the SR lessons with trusted and candidate states.
What maxqa knows about one Maximo: the estate scan, the notes the agent gets for an app, a message explained from MAXMESSAGES, and lessons with their track record. Captured from the reference environment.

Knowing what is different about your Maximo

No two Maximo estates match the manual. maxqa estate scan reads the Manage database once, read-only, and builds a configuration profile alongside the message catalogue. The profile holds customer-added fields and objects, cloned apps, security restrictions, conditional UI, automation scripts and their launch points, workflows, escalations, organisation and site settings against IBM defaults, and autonumber prefixes.

At run time the agent gets at most fourteen notes for the app under test, scoped to the test user’s site. For SR in the reference environment, that is a single line: the Service Request workflow starts from the Route Workflow button. A tester would want to know that before writing the steps, and so does the agent.

The same profile powers maxqa estate diff, which compares two environments or one environment across an upgrade. Run the pack on both sides of a MAS upgrade, then diff the configuration. You get a list of what changed and a list of what still works.

Preparing release evidence with automation while a person approves production is how Maintra treats agent-assisted delivery too.

What maxqa is, and what it is not

maxqa is in closed beta. It is a regression tool for the pack a Maximo functional team signs off before a patch, an upgrade or a move to MAS: the business processes that must still work on day one.

maxqa ismaxqa is not
A test tool for Maximo Manage that turns plain-English steps into replayable regression testsAn assistant clicking around production
Run on the tester’s machine against test and UAT environmentsA hosted service that holds your Maximo credentials
Verified on every run by REST, SQL and message checksA recorder whose pass depends on what a model saw
Model-agnostic: local Ollama, Claude or Codex subscriptions, Anthropic or OpenAI keysTied to one AI vendor
Readable YAML recordings that can be reviewed in a pull requestA black box nobody can audit

The time saved comes from replay. Once a flow is recorded, the eleven-test core suite runs unattended in about five minutes with no model calls, and it can run every night. Each run leaves screenshots, the result of every check, an HTML report and JUnit XML for a CI pipeline. That is the evidence a test lead attaches to a sign-off, produced without anyone clicking.

The beta covers the classic Manage UI on MAS 9.2 with DB2. Validation on Maximo 7.6, role-based Work Centers, single sign-on, MAS SaaS estates without database access, and parallel runs are on the beta roadmap.

Before your next regression cycle

  1. List the flows you click through by hand Work order approval, PR to PO to receipt, PM generation and storeroom issue cover most packs. Write each one as three to six plain-English steps.
  2. Give every test its own data Create the record in setup through REST with a run id in the description. Never test against a work order someone else might touch.
  3. Write the check before the steps Decide which stored field proves the test passed, and assert it with REST or SQL. Add a message check for the BMXAA code you expect.
  4. Scan the estate Read your message catalogue and configuration once, so the failures your tests hit are explained in your system’s own terms.
  5. Replay nightly, heal on break Run in auto mode. Look at the runs that needed the agent; they show you where the environment changed.

Let the model drive the browser. Never let it mark the exam.

Frequently asked questions

Frequently asked questions

Can AI automate Maximo regression testing?
Yes, if the agent only drives the browser and deterministic checks decide the result. In maxqa the agent works through plain-English steps, REST and SQL assertions verify the stored data, and the passing run is recorded so later runs replay with no model.
Why do Selenium tests break after a Maximo or MAS upgrade?
Most scripts target generated control ids and fixed page layouts. MAS changes the login page and wraps the classic UI in an iframe, and Maximo regenerates control ids. Targeting elements by kind and label, and waiting on Maximo's own event queue, avoids most of those breaks.
Does maxqa need a cloud AI service?
No. It runs on the tester's machine and works with a local Ollama model, the Claude or Codex command-line tools on an existing subscription, Anthropic or OpenAI API keys, or any OpenAI-compatible local server. Replays use no model at all.
How do you stop an AI agent from passing a broken test?
Require two keys. The agent must report success, and every REST, SQL and message assertion must pass. In the reference environment this caught a run where the model picked the wrong asset and Maximo still saved the record.
Is maxqa available to use?
maxqa is in closed beta. Teams preparing a patch cycle or a MAS upgrade can request beta access.
Does maxqa work without database access, for example on MAS SaaS?
The UI driver and REST checks work without it. Database access adds application metadata, the message catalogue, the estate profile and SQL assertions. Reading metadata over REST for estates without database access is on the roadmap.

For Maximo teams

Stop clicking through the same regression pack.

maxqa is in closed beta. If your team signs off Maximo business processes by hand before every patch or MAS upgrade, tell us which flows you test and we will run them with you.

Request beta access