msw: POST is not intercepted in a dockerised enviroment that uses a network bridge

Environment

docker on windows running linux containers docker version

Client: Docker Engine - Community
 Cloud integration: 1.0.1
 Version:           19.03.13
 API version:       1.40
 Go version:        go1.13.15
 Git commit:        4484c46d9d
 Built:             Wed Sep 16 17:00:27 2020
 OS/Arch:           windows/amd64
 Experimental:      false
Server: Docker Engine - Community
 Engine:
  Version:          19.03.13
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       4484c46d9d
  Built:            Wed Sep 16 17:07:04 2020
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.3.7
  GitCommit:        8fba4e9a7d01810a393d5d25a3621dc101981175
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

Request handlers

import React from 'react';
import ReactDOM from 'react-dom';
import './css/index.css';
import App from './components/App';
import { CookiesProvider } from 'react-cookie';
import { MockedRequest } from 'msw';

async function render() {
    if (process.env.REACT_APP_MOCKED) {
        document.cookie = 'JSESSIONID=GSGJSGJSHGSH';
        document.cookie = 'name="Blueberry Developer"';
        // eslint-disable-next-line
        const { worker } = require("./mocks/browser");
        await worker.start({
            waitUntilReady: true,
            serviceWorker: {
                url: `${process.env.PUBLIC_URL}/mockServiceWorker.js`,
            },
            onUnhandledRequest: (req: MockedRequest) => {
                console.error('Found an unhandled %s request to %s', req.method, req.url.href);
            },
        });
    }

    ReactDOM.render(
        <CookiesProvider>
            <React.StrictMode>
                <App />
            </React.StrictMode>
        </CookiesProvider>,
        document.getElementById('root'),
    );
}

render();

Actual request

    function createGitHubRepo(payload: ICreateRepo): void {
        fetch(`${backEndHost}/api/v1/repos/create`, {
            method: 'POST',
            mode: 'cors',
            credentials: 'include',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ name: payload.repoName, description: payload.description }),
        })
            .then(async (res) => {
                if (res.status === 201) {
                    const r = await res.json();
                    setState({ success: true, error: false, body: r });
                } else if ([400, 415].includes(res.status)) {
                    setState({ success: false, error: true, body: { clone_url: '', url: '' } });
                } else if (res.status === 500) {
                    setState({ success: false, error: true, body: { clone_url: '', url: '' } });
                }
            })
            .catch((err) => {
                throw new Error(err);
            });
    }

Current behavior

Architecture: I have my react App running on docker fully mocked via MSW. Command run docker run -it --rm --network app --name catalogue -p 3001:3001 -v "C:\Projects\step-enablement-catalogue\web":/workspace–bind 0.0.0.0 -w /workspace–entrypoint “npm” node:lts run mock

I run my playwright tests within a docker container with the following command: docker run -it --network app --rm --name playwright -v "C:\Projects\step-enablement-catalogue\web\e2e_tests":/workspace -e TEST_URL=http://catalogue:3001 -w /workspace --entrypoint “npm” mcr.microsoft.com/playwright run test-pipeline

The two containers see each other via a network bridge named “app” (command: docker network create --driver bridge app )

What is happening?

Scenarios executed:

  1. App running on my computer (win 10), Tests executed via my computer —> all tests pass including those that fires POST requests (MSW responds well)
  2. App running on docker container, Tests executed via my computer —> all tests pass including those that fires POST requests (MSW responds well)
  3. App running on docker container, Tests executed within a different container —> Not all tests pass, the one that fires POST request are not triggering an MSW response

Expected behavior

Test should pass even in the third scenario an MSW should respond to POST even within a container

Screenshots

Screenshots for first and second scenarios:

image

image

Unfortunately as the dockerised version runs headless I can only provide console logs captured from playwright code and a screenshot captured from playwright tests. As you can see the Test has clicked on the “Submit” button and from logs you can see that request POST has been fired properly but MSW doesn’t seem to be responding.

image

output.txt

As you can see the POST goes to 404 ` console.log POST http://catalogue:3001/api/v1/repos/create {“user-agent”:“Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/88.0.4324.0 Safari/537.36”,“content-type”:“application/json”,“accept”:“/”,“origin”:“http://catalogue:3001”,“referer”:“http://catalogue:3001/step-enablement-github-service",“cookie”:"JSESSIONID=GSGJSGJSHGSH; name="Blueberry Developer"”}   at utils/commonUtils.ts:34:17

 console.log 404 http://catalogue:3001/api/v1/repos/create`

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 18 (9 by maintainers)

Most upvoted comments

it’s already headless, I have created the config file jest-playwright.config.js with that option. I try to recap the steps:

1. Create create for your domain ( catalogue)

2. Create CA in your local pc

3. Copy all created file under a folder shared with containers

4. Use certificate in your react application

5. Install certificate in your test container

I have seen that you have used NODE_EXTRA_CA_CERTS. In this case is not useful because you are using the browser. Be sure to install the CA certificate.

I have added also this two important steps in my case

RUN mkdir -p $HOME/.pki/nssdb
RUN certutil -d sql:$HOME/.pki/nssdb -N --empty-password

To create a space for Chromium to load certificate

Grande Marco, funziona adesso! The reasons to why it wasn’t working for me is because I am mounting the directory containing the certs after building the image and of course that didn’t work(image had the cert directory empty). As soon as I added an additional copy (copy the certs from local to docker) the installation did pick the certs and installed them. I learned quite a lot from this exercise and once again thanks for your patience and direction

Thanks alot

Hi @fasatrix I have made this example repo https://github.com/marcosvega91/msw-ssl

I don’t have used docker for this example but it should be the same. Anyway, I’ll add it later.

In your docker environment, you could create a certificate on your container using mkcert for the domain catalogue and then run your test using the address https://catalogue:3001 instead of http://catalogue:3001

Grazie mille Marco and amazing response. Will let you how how it goes

Hi @fasatrix I have made this example repo https://github.com/marcosvega91/msw-ssl

I don’t have used docker for this example but it should be the same. Anyway, I’ll add it later.

In your docker environment, you could create a certificate on your container using mkcert for the domain catalogue and then run your test using the address https://catalogue:3001 instead of http://catalogue:3001

Thank you too, this discussion will be useful for other person too I think ☺️. I’ll close the issue, alla prossima 😉

it’s already headless, I have created the config file jest-playwright.config.js with that option. I try to recap the steps:

  1. Create create for your domain ( catalogue)
  2. Create CA in your local pc
  3. Copy all created file under a folder shared with containers
  4. Use certificate in your react application
  5. Install certificate in your test container

I have seen that you have used NODE_EXTRA_CA_CERTS. In this case is not useful because you are using the browser. Be sure to install the CA certificate.

I have added also this two important steps in my case

RUN mkdir -p $HOME/.pki/nssdb
RUN certutil -d sql:$HOME/.pki/nssdb -N --empty-password

To create a space for Chromium to load certificate