strangeQuirks
strangeQuirks

Reputation: 5920

Testing a cloudflare worker with HTMLRewriter fails as its undefined

I have a test to test my cloudflare worker that looks like this:

const workerScript = fs.readFileSync(
    path.resolve(__dirname, '../pkg-prd/worker.js'),
    'utf8'
);

describe('worker unit test', function () {
    // this.timeout(60000);
    let worker;

    beforeEach(() => {
        worker = new Cloudworker(workerScript, {
            bindings: {
                HTMLRewriter
            },
        });
    });

    it('tests requests and responses', async () => {
        const request = new Cloudworker.Request('https://www.example.com/pathname')
        const response = await worker.dispatch(request);
        console.log(response);
        // const body = await response.json();
        expect(response.status).to.eql(200);
        // expect(body).to.eql({message: 'Hello mocha!'});
    });
});

In my worker I do something like this:

 const response = await fetch(BASE_URL, request);
        const modifiedResponse = new Response(response.body, response);

        // Remove the webflow badge
        class ElementHandler {
            element(element) {
                element.append('<style type="text/css">body .w-webflow-badge {display: none!important}</style>', {html: true})
            }
        }
        console.log(3);

        return new HTMLRewriter()
            .on('head', new ElementHandler()).transform(modifiedResponse);

Now when i run my test I get this error message:

  ● worker unit test › tests requests and responses

TypeError: Cannot read property 'transform' of undefined

  at evalmachine.<anonymous>:1:1364
  at FetchEvent.respondWith (node_modules/@dollarshaveclub/cloudworker/lib/cloudworker.js:39:17)

What seems to be wrong?

HTMLRewriter i created looks like this:

function HTMLRewriter() {
    const elementHandler = {};

    const on = (selector, handler) => {
        if (handler && handler.element) {
            if (!elementHandler[selector]) {
                elementHandler[selector] = [];
            }
            elementHandler[selector].push(handler.element.bind(handler));
        }
    };

    const transform = async response => {
        const tempResponse = response.clone();

        const doc = HTMLParser.parse(await tempResponse.text());
        Object.keys(elementHandler).forEach(selector => {
            const el = doc.querySelector(selector);
            if (el) {
                elementHandler[selector].map(callback => {
                    callback(new _Element(el));
                });
            }
        });

        return new Response(doc.toString(), response);
    };

    return {
        on,
        transform
    };
}

Upvotes: 1

Views: 1033

Answers (1)

Kenton Varda
Kenton Varda

Reputation: 45171

Since HTMLRewriter() is called with new, the function needs to be a constructor. In JavaScript, a constructor function should set properties on this and should not return a value. But, your function is written to return a value.

So, try changing this:

return {
    on,
    transform
};

To this:

this.on = on;
this.transform = transform;

Upvotes: 1

Related Questions