3

we are trying to implement functional testing using testcafe. Because of our complex backend systems, we will not be able to hit the actual API in some scenario (like OTP, backend account lock) without manual intervention. To circumvent this we have decided to run a stub server for certain endpoints.

In order to achieve this, we wanted to modify the URL of API in our test code. We thought of using a custom request hook to change the URL. Although the URL changes in the object, the browser hits the actual API URL.

import { RequestHook } from "testcafe";

class CustomRequestHook extends RequestHook {

   constructor() {
       super();
   }

   onRequest(requestEvent: any) {
   try {

        if (requestEvent.isAjax && requestEvent.requestOptions.isXhr && requestEvent.requestOptions.path.indexOf('.') === -1) {
    console.log(requestEvent.requestOptions.path);
    console.log("Before:", requestEvent.requestOptions.url);
    requestEvent.requestOptions.url = 'http://localhost:4200' + requestEvent.requestOptions.path;
    // requestEvent.requestOptions.host = 'localhost:4200';
    // requestEvent.requestOptions.hostname = 'localhost:4200';
    console.log("After:", requestEvent.requestOptions.url);
    requestEvent.requestOptions.headers['custom-header'] = 'value';
    // requestEvent.requestOptions.headers['host'] = 'localhost:4200';
  }
} catch (error) {
  console.log("Error:", error);

  // requestEvent.requestOptions.url = "www.google.com";
}
}
 onResponse(responseEvent: any) {
  console.log("response", responseEvent)
 }
}

export const CustomRequestHookInstance = new CustomRequestHook();
Alex Skorkin
  • 4,264
  • 3
  • 25
  • 47
Sudhir V
  • 243
  • 1
  • 2
  • 8

1 Answers1

3

Currently you can't change the destination URL of a request using the requestEvent.requestOptions.url property, I've created an issue about this: DevExpress/testcafe#2635. You should use the hostname, port and path properties:

requestEvent.requestOptions.hostname = 'localhost';
requestEvent.requestOptions.port     = 4200; 
Andrey Belym
  • 2,893
  • 8
  • 19
  • Hi @Andrey Belym, Thanks for response. I tried changing hostname, port and path as suggested but the tests are still hitting actual API instead of the modified one.
    `requestEvent.requestOptions.path = 'http://localhost:4200'+requestEvent.requestOptions.path; // requestEvent.requestOptions.url = 'http://localhost:4200'+requestEvent.requestOptions.path; requestEvent.requestOptions.hostname = 'localhost'; requestEvent.requestOptions.port = 4200;`
    – Sudhir V Jul 18 '18 at 02:38
  • 1
    There is a complex condition in your code: `requestEvent.isAjax && requestEvent.requestOptions.isXhr && requestEvent.requestOptions.path.indexOf('.') === -1`, I would log each part of it. Also, I can't find the `isXhr` property in the list of `requestEvent.requestOptions` properties: https://devexpress.github.io/testcafe/documentation/test-api/intercepting-http-requests/requestoptions-object.html – Andrey Belym Jul 18 '18 at 12:28
  • Removed all the conditions except checking the path for `api` (could have done with filters but will refactor after it works). Still no luck. Tried various combinations of hostname, host, protocol, url and path. `console.log(requestEvent.requestOptions.path); if (requestEvent.requestOptions.path.indexOf("/api") > -1) { console.log("comes inside"); .... other logic...... }` – Sudhir V Jul 19 '18 at 03:52