# Import JMeter, k6, and Locust Scripts

> Import JMeter test plans (.jmx), k6 scripts (.js), and Locust locustfiles (.py) as Loadster Protocol Bot scripts, and review what didn't translate.

Source: https://loadster.com/manual/protocol-scripts/importing-scripts/

If you already have load test scripts from another tool, Loadster can import them so you don't have to start over.
The importer accepts:

* **JMeter** test plans (`.jmx`, or `.xml`)
* **k6** scripts (`.js`)
* **Locust** locustfiles (`.py`)

Each import produces a [protocol script](https://loadster.com/manual/protocol-scripts/) for Protocol Bots, with HTTP steps, wait steps,
and sometimes [JavaScript Code Blocks](https://loadster.com/manual/code-blocks/). There's no importer for Browser Bot or Playwright
scripts, and there's no LoadRunner (VuGen) importer.

Every tool has its own concepts that don't map one-to-one, so the importer also gives you a report of anything it
couldn't translate or had to approximate. Expect to review the script and play it at least once before you load test
with it.

## Importing a Script into Loadster

You can start an import from a few places:

* On your project's **Scripts** tab, open the **Create Script** menu and choose **Import Script**.
* In the protocol script editor, click **Import** in the toolbar to import into the script you have open.
* On a brand new account with no projects yet, the dashboard's quick start offers a tile for each tool.

The import dialog asks for:

* **External Tool**: JMeter, k6, or Locust.
* **External File**: the file to import. You can't paste a script into the dialog, so save it to a file first.
* **Destination Script Name**: the name for the new script, filled in from the file name. When you import into an
  existing script, you choose instead whether to **Append** the imported steps to the end of the script or
  **Replace** its contents.
* **Base URL (optional)**: a host such as `https://example.com`. Some scripts use relative paths and set the host
  somewhere the importer can't see (a command line flag, an environment variable). If yours does, enter the host
  here, and Loadster puts it in front of any relative request URLs.

When the import finishes, the dialog links to the new script, plus any scenario or datasets the import created, and
shows the import report.

## Reviewing the Import Report

The import report has two lists:

* **Some items might need your attention:** things you'll probably need to fix by hand, like a CSV dataset that
  needs its rows uploaded, an assertion that couldn't be converted, or Groovy code that needs rewriting in JavaScript.
* **Other notes:** informational entries for what was converted and how, such as which requests were imported or that
  a random think time became a fixed wait.

Each entry names the part of the original script it came from, so you can find it in both places. Work through the
first list before you run a load test. The second list is worth a skim, especially the approximations.

## Importing JMeter Test Plans (.jmx)

The JMeter importer reads the test plan's XML and converts its HTTP Request samplers into HTTP steps, including the
method, URL, query parameters, request body, and headers.

What comes across from a JMeter test plan:

* **HTTP Request samplers** become HTTP steps. Other sampler types (JDBC, TCP, and so on) aren't converted.
* **HTTP Header Manager** headers become request headers, either on every following request or on a single request,
  depending on where the Header Manager sits.
* **HTTP Request Defaults** supply the protocol, host, and port for requests that don't have their own.
* **Extractors** become [capturing rules](https://loadster.com/manual/protocol-scripts/capturing-rules/): the Regular Expression
  Extractor becomes a regex rule, the Boundary Extractor a text boundary rule, the JSON Extractor a JSONPath rule,
  and the XPath Extractor an XPath rule.
* **Assertions** become [validation rules](https://loadster.com/manual/protocol-scripts/validation-rules/): Response Assertions on the
  status code or response text, Duration Assertions, Size Assertions, JSON Assertions, and XPath Assertions. A few
  variants are approximated, such as a "matches" Response Assertion, which becomes a JavaScript validation rule, and
  the report says so.
* **Timers** (constant, uniform random, and Gaussian random) become wait steps. Random timers become a fixed wait of
  their average delay.
* **Transaction Controllers** become a comment step followed by their requests, since transactions are only labels
  in Loadster.
* **If, While, Loop, and ForEach Controllers** become a code block that makes the same requests in JavaScript.
  Assertions and extractors inside those controllers aren't carried into the code block, so review it carefully.
* **CSV Data Set Config** creates an empty [dataset](https://loadster.com/manual/dynamic-datasets/) named after the CSV file and rewires
  the script's `${column}` references to it. Upload the rows from your CSV file to finish it.
* **Thread Groups** become a new [load test scenario](https://loadster.com/manual/load-test-scenarios/), with a bot group for each
  thread group, using its thread count, ramp-up, and duration.

What doesn't come across from a JMeter test plan:

* **JSR223 and BeanShell elements** (Groovy or BeanShell code) can't be translated automatically. The importer keeps
  the original code in a code block, commented out, for you to rewrite in JavaScript.
* **User Defined Variables** at the test plan level are left as `${name}` references, since Loadster has no global
  constants. Define them as variables or put the values inline.
* **HTTP Authorization Manager** settings aren't converted. Authentication headers set in a Header Manager do come
  across.
* **Arrival and throughput thread groups** don't produce a scenario, since Loadster doesn't model arrival rates. Set
  up the load in a scenario yourself.
* Disabled elements are skipped. The Cookie Manager, Cache Manager, and listeners aren't needed, because Loadster
  handles cookies and caching automatically and reports results on its own.

## Importing k6 Scripts (.js)

The k6 importer reads your script's default function without running it, and converts the calls it recognizes.

What comes across from a k6 script:

* **`http.get()`, `http.post()`, `http.request()`** and the other request functions become HTTP steps, including
  headers from the params object. URLs and bodies that are string literals or string constants come across as they
  are, and template literals like `` `${BASE_URL}/api` `` keep their `${...}` references.
* **`sleep()`** becomes a wait step. Note that k6 sleeps in seconds and Loadster waits in milliseconds; the importer
  converts it for you.
* **`check()`** predicates that test the status code (`r.status === 200`) become status validation rules, and those
  that test `.includes('text')` become text validation rules. Other checks are listed in the report to add by hand.
* **`res.json('path')`** assignments become JSONPath capturing rules.
* **`group()`** becomes a comment step followed by the grouped steps.
* **`options.stages`**, or `options.vus` with `options.duration`, become a new load test scenario. Stage
  durations are rounded up to whole minutes.

What doesn't come across from a k6 script:

* Other logic (conditionals, loops, other function calls) is copied as-is into
  [JavaScript Code Blocks](https://loadster.com/manual/code-blocks/). Code blocks look a lot like k6, but the functions aren't identical,
  so review them. For example, `sleep` takes milliseconds and the response body is `response.string()`.
* **`setup()`** and **`teardown()`** functions aren't imported.
* Request params other than headers, such as tags, timeouts, and auth, aren't imported.
* **`options.scenarios`**, **`thresholds`**, and **`iterations`** aren't read.
* Request bodies built from expressions, rather than string literals or constants, need to be set by hand.

## Importing Locust Scripts (locustfile.py)

The Locust importer scans your locustfile for an `HttpUser` or `FastHttpUser` class and imports each `@task` method,
plus `on_start` and `on_stop`, in the order they appear in the file.

What comes across from a Locust script:

* **`self.client.get()`**, `post()`, and the other client methods become HTTP steps, including `json=`, `data=`, and
  `headers=` arguments. Each call needs to fit on one line.
* **`host`** on the user class is used as the host for relative URLs.
* **f-strings** in URLs keep their references, so `f"/items/{item_id}"` becomes `/items/${item_id}`.
* **`r.json()["key"]`** assignments become JSONPath capturing rules.
* **`wait_time`** (`between`, `constant`, or `constant_pacing`) becomes a wait step after each task, using the
  average of a `between` range.
* Each task starts with a comment step naming it.

What doesn't come across from a Locust script:

* Other lines of Python aren't converted. Each one is listed in the report, so you can recreate it as a step or a
  code block.
* Locust picks tasks at random (optionally weighted), but a Loadster script runs its steps in order. If your
  locustfile has several tasks, reorder them, or split them into separate scripts and bot groups.
* Users and spawn rate come from the Locust command line or a load shape, not the file, so no scenario is created.
  Build a matching [load test scenario](https://loadster.com/manual/load-test-scenarios/) yourself.
* `params=`, `name=`, `auth=`, and other keyword arguments aren't imported, so add query parameters to the URL by
  hand.
* JSON bodies are copied from the Python source text, and a Python dict isn't always valid JSON (single quotes, for
  example), so check them.

## Importing Scripts With an AI Assistant Over MCP

If you've connected an AI assistant to Loadster's [MCP server](https://loadster.com/manual/mcp/), it can import scripts too. The
`import_script` tool takes the file's contents as text and imports it into an existing script, returning the same
items that need attention. This is handy when the assistant can read the file from your repository, since it can then
work through the report with you.

## After Importing a Load Test Script

An imported script is a starting point. Before you load test with it:

1. **Work through the import report**, starting with the items that need your attention.
2. **Upload rows to any datasets** the import created. They start out empty.
3. **Play the script** in the editor with a single bot and look at each step's response. This catches missing hosts,
   bodies that need fixing, and session values that need a [capturing rule](https://loadster.com/manual/protocol-scripts/capturing-rules/).
4. **Review the scenario the import created**, if there is one, before you launch a test with it. Loadster bases it on the
   original script's load settings, but it's worth confirming the bot counts, ramp-up, and duration.

If your original script was recorded from a browser, it's sometimes quicker to [record a fresh
script](https://loadster.com/manual/protocol-scripts/) with the free browser extension, or to write a
[browser script](https://loadster.com/manual/browser-scripts/) that tests the site with real browsers.

