Skip to main content
QA Wolf accepts file uploads via a two-step signed URL process:
  1. Request a signed upload URL from the QA Wolf API
  2. Upload your file directly to that URL
This method works for any supported file type and can be used for one-off uploads or as part of a custom automation.

Prerequisites

  • Your QAWOLF_API_KEY — available under Workspace Name → Workspace Settings → Integrations → API Access

Step 1: Generate a signed URL

Make a GET request with the filename (including extension) as the file query parameter.
curl -X GET \
  "https://app.qawolf.com/api/v0/run-inputs-executables-signed-urls?file=YOUR_FILENAME" \
  -H "Authorization: Bearer $QAWOLF_API_KEY"
On success, you’ll receive:
{
  "fileLocation": "$TEAM_ID/YOUR_FILENAME",
  "playgroundFileLocation": "YOUR_FILENAME",
  "signedUrl": "https://..."
}
Copy the signedUrl — you’ll use it in the next step.
The signed URL is temporary. Upload your file promptly after generating it.

Step 2: Upload the file

Use the signedUrl from Step 1 to upload your file via a PUT request.
curl -X PUT \
  --header "Content-Type: application/octet-stream" \
  --data-binary @/path/to/your/file \
  "$SIGNED_URL"
Once this completes successfully, the file is available in QA Wolf.

Use an uploaded file in a flow

Mobile apps

Reference the uploaded file using the RUN_INPUT_PATH environment variable, which is set automatically when a file is uploaded via the API.
const APK_PATH = `/home/wolf/run-inputs-executables/${process.env.RUN_INPUT_PATH || "default-file.apk"}`;

const driver = await wdio.startAndroid({
  "appium:app": APK_PATH,
});
For mobile testing, the best approach is to upload new builds automatically as part of your CI/CD pipeline rather than uploading manually. See Integrating your mobile CI pipeline for how to set this up.

Web file upload

Use Playwright’s filechooser event to intercept the file dialog and set the uploaded file programmatically.
const fileName = `${process.env.TEAM_STORAGE_DIR}/fileNameHere`;

page.once(
  "filechooser",
  (chooser) => void chooser.setFiles(fileName).catch(console.error)
);

await page.getByText("Upload file").click();
Use page.once rather than page.on. page.once registers a one-time event listener that automatically unregisters after the first use. Using page.on adds a persistent listener that may interfere with subsequent file uploads in the same flow.

PDF viewing

Use the internal PDF viewer to open an uploaded PDF file in a flow.
const invoicePath = `${process.env.TEAM_STORAGE_DIR}/invoices/invoice-1.pdf`;

const pdfPage = await context.newPage();
await pdfPage.goto("http://pdf-viewer.psc.qaw.internal");

pdfPage.once(
  "filechooser",
  (chooser) => void chooser.setFiles(invoicePath).catch(console.error)
);

await pdfPage.waitForTimeout(4000);
await pdfPage.click("#openFile");

Supported file types

Use a static filename based on the environment (e.g., app-staging.ipa) so tests always reference the latest build. See Integrating your mobile CI pipeline for how to automate this as part of your build process.
ZIP files can be used to bundle multiple assets for a single upload. Ensure the contents follow any structure expected by the tests that will consume them.
CSV files are typically used as test data inputs. Use a consistent filename so flows always pick up the latest version.
PDF files can be uploaded for use in test flows that involve document handling or validation.
Last modified on April 1, 2026