Capturing iOS Simulator Network Traffic with Appium

February 20, 2026 · 14 min read · Mobile Testing

HeadSpin Platform
Automated & amp; manual testing made easygoing through data science insights.
Differentiating capabilities:
  • Extensive end-to-end mechanization of QA process
  • Relative analysis of app performance against peers
  • Continuous monitoring of app performance using synthetic data for higher availableness of apps
  • Easy-to-use developer friendly program
cloudtest go
Low-priced Existent Device Testing for Emerging Teams
cloudtest go
Affordable Real Device Testing for Digital Enterprises
cloudtest go
The Ultimate Solution for a Powerful Blend of Functional & amp; Performance Testing!
cyol
TEM
New
Centralized mobile exam execution in cloud
cyol
Enhance Your Accessibility Testing With HeadSpin
cyol
Automate camera-based testing

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

retail

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

Capturing iOS Simulator Network Traffic with AppiumCapturing iOS Simulator Network Traffic with Appium

Capturing iOS Simulator Network Traffic with Appium

Published on
March 27, 2019
Updated on
Published on
April 20, 2022
Updated on
 by 
 Jonathan LippsJonathan Lipps
Jonathan Lipps

The next couple editions of Appium Pro will be about capturing meshwork requests make by device during a exam. If we can admittance network requests from our exam code, we could make asseveration based on specific requests being sent to our server, or assert that the data in network responses are displayed in the UI. We can also capture meshing data to help debug issue when tests fail. We could also make assertions on the performance of our network calls, by checking the timing between asking and responses.

It & # x27; s comparatively easy to get network logs from Chrome and Safari sessions, since the browser debug ports make that information available, but what if we want to capture requests made by aboriginal apps?

The solution is to use a man-in-the-middle procurator. A proxy of this sort is a program which we insert between the device and the cyberspace. We recite the device to route all requests through our procurator, which tape the traffic as it passes through. Not only make it record it, but the proxy we will be using can besides be configured tomodifythe traffic. This opens up more potential use in testing: we can test the failure event when sure urls can & # x27; t be attain, and we can change responses to suit our want for consistent data.

Man-in-the-middle proxies also do a lot of tricky work breaking the protection establish into network systems. Capturing someone & # x27; s encrypted HTTPS traffic is what malicious assailant would want to do. We are but humble testers, but how is the system to cognize that? The proxy does a lot of work to give us forge authority to decrypt encrypted network traffic, once we perform some initial apparatus.

With a placeholder we can evenmodifythe meshing responses our device receives, allowing us to test with less random value. We can also use this proficiency to force the app into a particular state we want to test. All from within our test code, imply no change to the app.

For these articles, we will use a proxy calledmitmproxy. Much of the web examination and Selenium world is utilise to using Browsermob Proxy, but I ran into many difficulties trying to use it. As of this writing, Browsermob Proxy hasn & # x27; t been updated in two years and has some hard-and-fast limitations. For example, Browsermob proxy is ineffective to forward HTTPS requests which target an IP address directly instead of using a hostname. This is what my Android emulators do, regardless of the way my app is written.

Mitmproxy has an active ecosystem, modern tools, and spate of helpful documentation. I think we benefit from its wide use by researchers and security professionals rather than just quizzer.

Perhaps mitmproxy & # x27; s drawback is that it is publish for Python developers, and hasn & # x27; t been utilize much in testing to this date. I & # x27; d like to change this. The representative codification in today & # x27; s edition will be in Javascript, and in a later edition I plan on introducing a package for interacting with mitmproxy from Java.

Alright, on to the setup!

Setting up mitmproxy for iOS Simulators

Our goal hither is to run mitmproxy and get traffic from the iOS simulator pass through the proxy on it & # x27; s way to the internet. Then we can inspect requests which mitmproxy logs. First we & # x27; ll set up everything manually, and so put together the Python script which go it all in the context of a test.

Whenever in doubt, I suggest reading the first respective page of themitmproxy documentation. It helps to de-mystifty what we & # x27; re trying to put together and may help you get back on the rails of this tutorial if you chance issues.

Install mitmproxy. You may need to make sure you have Python3 andpip3 installed first. Installing this way is required for the Javascript library we will be using afterwards.

sudo pip3 install mitmproxy

And then run it:

For autonomous testing across multiple user personas, check out SUSATest — it explores your app like 10 different real users.


mitmproxy

The proxy scat on localhost port8080 by default. The empty pane it displays should fill up with network traffic once we configure our simulator to point to it.

iOS simulator don & # x27; t have their own settings for configuring a proxy, but they use the MacOS native meshing proxies. So the next step is to configure the entire host computer to use our mitmproxy. This mean that the meshwork traffic from whatever else our computer is doing will be desegregate in with the simulator traffic, but we can strain it later.

Open the Network Preferences, click onAdvanced, and click on theProxies tab.

Network proxy settings

There are several kinds of proxy available, we want to enable both theWeb Proxy (HTTP) andSecure Web Proxy (HTTPS). Check both proxy types and input the address of our mitmproxy server:0.0.0.0 on port 8080. Click Ok and Apply.

Network proxy settings set

Now, all scheme traffic should be going through the procurator. Let & # x27; s ensure real quick. Openhttp: //appium.io, and the page should load. Look at the mitmproxy UI and we should see some related net requests (use arrow key to scroll down).

Now check https: //appiumpro.com, it should fail. This is an HTTPS website and we haven & # x27; t set our system to trust the mitmproxy ssl certificate. We & # x27; re actually not travel to do that at all because we only need to set it up for the iOS simulator, and trusting the certificate on the OS point will leave us unsecured if we forget to untrust it after we finish testing.

Succeeding launching an iOS simulator and get the like check. Visitinghttp: //appium.ioin mobile Safari should work, whilehttps: //appiumpro.comshould neglect to lade.

Now we desire to establish the mitmproxy ssl certificate on the simulator. Navigate to a special url hosted by mitmproxy:http: //mitm.it. Click on the Apple logo and postdate the instructions to install the certificate on the simulator.

New instructions for iOS 12.2 and later: iOS 12.2 changed the UI for intalling certificates. The next step, if to open the Settings app and go to General- & gt; Profiles tap on the mitmproxy profile and tap & # x27; establish & # x27; in the upper right corner. Continue with the next step below.

After following prompts and tapping theinstall button in the upper right nook, there & # x27; s still one more step! Often, the new certificate is not amply swear by default. Open the Settings app and go to General- & gt; About- & gt; Certificate Trust Settings and enable full trust for the mitmproxy certificate. Now we should be able to regardhttps: //appiumpro.comin Safari.

Traffic from Safari and aboriginal apps should now be log in the mitmproxy UI!

Automating Certificate Installation

I list the manual measure above because it & # x27; s easygoing to debug and figure out if your setup is correct. Once running this all the time, if you have a new simulator to test on, you shouldn & # x27; t get to perform this manual employment. Appium can automate instal the certificate.

Use the mobile: installCertificatecommand, passing it a base64 encoded string of the mitmproxy certificate. Appium will automatise the settings app and trustfulness it for you.

Once mitmproxy is run erst, the security file are relieve to your home directory, so that & # x27; s where we say them from.

Here & # x27; s how I do it in our model test scripts:

let certificatePath = path.resolve (os.homedir (), '.mitmproxy ', 'mitmproxy-ca-cert.pem ') let certificate = await fs.readFile (certificatePath) await driver.executeScript ('mobile: installCertificate ', [{content: certificate.toString ('base64 ')}])

Capturing Traffic Within a Node.js Test Script

Let & # x27; s inclose codification to start mitmproxy before our examination, then filter and access the captured traffic so we can make assertion on it.

There are a couple different approaches to this. What I genuinely want is the ability to programmatically start mitmproxy and access the requests within my examination. Mitmproxy is designed with a nicely-featured addon fabric which supports plugins written in Python. The way the designers expects you to run mitmproxy is as a standalone service, and passing python playscript files to it using the-scommandline flag. We could indite a python addon and start/stop the placeholder as a separate cuticle operation, but I want to avoid that if I can.

Instead, I found aoutstanding little Node.js modulewhich starts mitmproxy as a separate summons and loads a special Python addon which opens a websocket connection so that we can get information in our Javascript code while the placeholder is scarper.

The undermentioned tryout open our usual demo app,TheApp, opens our pickerwheel demo, and tap the button. This action outcome in the app sending a request tohistory.muffinlabs.comwhich returns some historic event for the app to expose.

The test starts mitmproxy and logs all requests post by the app to an raiment. At the end of the test, we verify that the request we expected the app to send was so sent.

let test = require ('ava ') let fs = require ('fs-extra ') let os = require ('os ') let path = require ('path ') let {remote} = require ('webdriverio ') let Mitmproxy = require ('mitmproxy ') .default let proxy, driver let interceptedMessages = [] // this function will get called every time the placeholder intercepts a request let requestHandler = (message) = > {let req = message.request console.log (' * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ') console.log ('mitmproxy tap a asking ') console.log (req.method) console.log (req.rawUrl) console.log (message.requestBody.toString ()) console.log (' * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ') interceptedMessages.push (message)} test.before (async t = > {// showtime mitmproxy proxy = await Mitmproxy.Create (requestHandler, [], true, true) driver = await remote ({hostname: 'localhost ', embrasure: 4723, path: '/wd/hub ', capabilities: {platformName: 'iOS ', platformVersion: '12.1 ', deviceName: 'iPhone XS ', automationName: 'XCUITest ', app: 'https: //github.com/cloudgrey-io/the-app/releases/download/v1.9.0/TheApp-v1.9.0.app.zip ' // in order to download, you may ask to establish the mitmproxy certificate on your operating scheme first. Or download the app and supersede this capability with the path to your app.}, logLevel: 'silent'}) // if the mitmproxy certificate was not installed manually already. Only needs to run once per simulator let certificatePath = path.resolve (os.homedir (), '.mitmproxy ', 'mitmproxy-ca-cert.pem ') let certificate = await fs.readFile (certificatePath) await driver.executeScript ('mobile: installCertificate ', [{message: certificate.toString ('base64 ')}])}) test ('getting the event for a day, via request to history.muffinlabs.com ', async t = > {let pickerDemo = await driver. $ ('~Picker Demo ') wait pickerDemo.click () let button = await driver. $ ('~learnMore ') expect button.click () // wait for alert let alertIsPresent = async () = > {try {return await driver.getAlertText ();} catch {return false;}} await driver.waitUntil (alertIsPresent, 4000) await driver.dismissAlert () t.true (interceptedMessages.length > 0) t.true (interceptedMessages.some (m = > m.request.rawUrl == 'https: //history.muffinlabs.com/date/1/1 '))}) test.after.always (async t = > {t.log ('shutting down ') look proxy.shutdown () await driver.deleteSession ()})

Modifying Network Responses Recieved By The Device

Mitmproxy let us to get even more clever. Just modify a couple lines in the test above, we can intercept the app & # x27; s request tohistory.muffinlabs.comand rewrite the message of the response to comprise the data of our choosing.

This can be useful in getting the app into a predictable state. The current code select a random historical case to display every time, but we can answer with a individual event of our choosing and force the app to exhibit what we want. We can also force the UI to display specific values, so we can prove long strings, negative figure, fault state, etc, without having to actually set up the necessary context on the backend. All this can be done from the exam script!

let test = require ('ava ') let {remote} = require ('webdriverio ') let Mitmproxy = require ('mitmproxy ') .default let procurator, driver let interceptedMessages = [] // this is the reaction we will retrovert from our proxy, rather of what the site usually retrovert let injectedResponse = {date: `` January 1 '', url: `` https: //wikipedia.org/wiki/January_1 '', information: {Events: [{yr: `` 2019 '', schoolbook: `` Tests Passed '',}]}} let requestHandler = (message) = > {message.setResponseBody (Buffer.from (JSON.stringify (injectedResponse), 'utf8 '))} test.before (async t = > {proxy = await Mitmproxy.Create (requestHandler, [], true, true) driver = await remote ({hostname: 'localhost ', port: 4723, path: '/wd/hub ', capabilities: {platformName: 'iOS ', platformVersion: '12.1 ', deviceName: 'iPhone XS ', automationName: 'XCUITest ', app: 'https: //github.com/cloudgrey-io/the-app/releases/download/v1.9.0/TheApp-v1.9.0.app.zip ' // in order to download, you may need to install the mitmproxy certificate on your operating system first. Or download the app and supplant this capability with the path to your app.}, logLevel: 'silent'})}) test (` insert our own event for a day, asseverate that it 's displayed `, async t = > {let pickerDemo = await driver. $ ('~Picker Demo ') look pickerDemo.click () let button = await driver. $ ('~learnMore ') await button.click () // wait for alert let alertIsPresent = async () = > {try {return await driver.getAlertText ();} catch {return false;}} expect driver.waitUntil (alertIsPresent, 4000) let alertText = await driver.getAlertText () await driver.dismissAlert () // assert that the alertText is the like as the packet we shoot t.true (/Tests Passed/.test (alertText))}) test.after.always (async t = > {t.log ('shutting down ') await proxy.shutdown () await driver.deleteSession ()})

That & # x27; s all for this week.Sample code is on github, as usual. Adjacent hebdomad, I & # x27; ll demo how to create the same setup with Android Emulators (spoiler: it & # x27; s harder).

Author & # x27; s Profile

Jonathan Lipps

LinkedIn
Author & # x27; s Profile

Piali Mazumdar

Lead, Content Marketing, HeadSpin Inc.

Piali is a dynamic and results-driven Content Marketing Specialist with 8+ days of experience in crafting engaging narratives and marketing collateral across diverse industriousness. She excels in collaborate with cross-functional teams to develop advanced content strategies and present compelling, authentic, and impactful content that vibrate with target audiences and enhances make genuineness.

LinkedIn

Capturing iOS Simulator Network Traffic with Appium

4 Parts

regression intelligence blog
-

Regression Intelligence practical guide for forward-looking user (Part 3)

Coming Soon
Regression Intelligence practical guide for advanced users
-

Regression Intelligence pragmatic guide for advanced users (Part 4)

Coming Soon

Discover how HeadSpin can authorize your line with superior testing capabilities

Our Platform enables you to:
accelerate time-to-market
Accelerate time-to-market, gaining a competitive edge
faster development cycles
Boost developer/QA productiveness with faster evolution rhythm
automated buil-over-build regression testing
Automate build-over-build regression testing for coherent results
gain better visibility into functional & performance issues
Gain best visibility into functional and performance topic
reduce mean time
Reduce mean time to identify/resolve during tryout, QA, and production
evaluate audio, video & qoe
Evaluate audio, picture, and contented caliber of experience (QoE) effortlessly
The trusted choice for spherical initiative
Adobe
Hargreaves Lansdown
Truecaller
Crazylabs
Nedbank
Numeracle
Veryon
Close

Discover how HeadSpin can empower your business with superior quiz capabilities

Our Platform enables you to:
accelerate time-to-market
Accelerate time-to-market, gaining a competitive edge
faster development cycles
Boost developer/QA productivity with faster development cycles
automated buil-over-build regression testing
Automate build-over-build fixation testing for consistent results
gain better visibility into functional & performance issues
Gain better visibility into functional and performance issues
reduce mean time
Reduce mean time to identify/resolve during examination, QA, and product
evaluate audio, video & qoe
Evaluate audio, picture, and content quality of experience (QoE) effortlessly
The trusted choice for global enterprises
Close

Discover how HeadSpin can empower your business with superior screen capabilities

Our Platform enables you to:
accelerate time-to-market
Accelerate time-to-market, gaining a competitory edge
faster development cycles
Boost developer/QA productivity with faster development cycle
automated buil-over-build regression testing
Automate build-over-build fixation testing for consistent results
gain better visibility into functional & performance issues
Gain better visibility into functional and performance issues
reduce mean time
Reduce mean time to identify/resolve during test, QA, and production
evaluate audio, video & qoe
Evaluate audio, video, and content character of experience (QoE) effortlessly
The sure choice for worldwide enterprises
Close

Connet Now

Wipro LogoVMLYR Logo
Close
Book a Meeting
Products
footer down arrow
Solutions
footer down arrow
Industries
footer down arrow
Features
footer down arrow
Support
footer down arrow
Resource Center
footer down arrow
Why Choose HeadSpin?
footer down arrow
Copyright © 2026 HeadSpin, Inc. All Rights Reserved.

Automate This With SUSA

Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts needed.

Try SUSA Free

Test Your App Autonomously

Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.

Try SUSA Free