github.com/quickfeed/quickfeed@v0.0.0-20240507093252-ed8ca812a09c/public/src/__tests__/TestHelpers.ts (about)

     1  import { createOvermindMock } from "overmind"
     2  import { Browser, Builder, IRectangle, ThenableWebDriver } from "selenium-webdriver"
     3  import { config } from "../overmind"
     4  import { State } from "../overmind/state"
     5  import { SubType } from "overmind/lib/internalTypes"
     6  import { ReviewState } from "../overmind/namespaces/review/state"
     7  import { ApiClient } from "../overmind/effects"
     8  
     9  export const isOverlapping = (rect: IRectangle, rect2: IRectangle) => {
    10      return (rect.x < rect2.x + rect2.width &&
    11          rect.x + rect.width > rect2.x &&
    12          rect.y < rect2.y + rect2.height &&
    13          rect.height + rect.y > rect2.y)
    14  }
    15  
    16  // getBuilders returns an array of builders for all the browsers that are supported.
    17  // Supported browsers must be defined in the config.json file.
    18  // These builders require you to have web driver executables in your PATH.
    19  const getBuilders = (): Builder[] => {
    20      const config = require("./config.json")
    21      const builders: Builder[] = []
    22      Object.entries(Browser).forEach(([key, value]) => {
    23          if (key in config.BROWSERS && config.BROWSERS[key]) {
    24              const builder = createBuilder(value)
    25              builders.push(builder)
    26          }
    27      })
    28      if (builders.length === 0) {
    29          throw new Error("No supported browsers found. Please check the config.json file.")
    30      }
    31      return builders
    32  }
    33  
    34  const createBuilder = (browser: string) => {
    35      return new Builder().forBrowser(browser)
    36  }
    37  
    38  // getBaseUrl returns the base url to be used for the tests.
    39  export const getBaseUrl = (): string => {
    40      const config = require("./config.json")
    41      let url = config.BASE_URL as string
    42      if (url.endsWith("/")) {
    43          url = url.slice(0, -1)
    44      }
    45      return url
    46  }
    47  
    48  /**
    49   *  setupDrivers returns an array of drivers for all the browsers that are supported.
    50   *  @path (optional) the path to load in the browser.
    51   *  @example: setupDrivers("/path/to/page")
    52   */
    53  export const setupDrivers = (path?: string): ThenableWebDriver[] => {
    54      const baseUrl = getBaseUrl()
    55      const builders = getBuilders()
    56      const drivers = builders.map(driver => driver.build())
    57  
    58      beforeAll(async () => {
    59          // Open the page to be tested in all browsers, before running tests
    60          await Promise.all(drivers.map(driver => driver.get(baseUrl + (path ? path : ""))))
    61      })
    62  
    63      afterAll(async () => {
    64          // Close all drivers after the tests are done
    65          await Promise.all(drivers.map(driver => driver.quit()))
    66      })
    67  
    68      return drivers
    69  }
    70  
    71  /** initializeOvermind creates a mock Overmind instance with the given state, reviewState, and mockedEffects.
    72   * @param state the state to initialize the mock with
    73   * @param mockedEffects the mocked effects to initialize the mock with
    74   * NOTE: Directly setting derived values in the state is not supported.
    75  */
    76  export const initializeOvermind = (state: Partial<State & SubType<{ review: Partial<ReviewState>; }, object>>, mockedApi?: ApiClient) => {
    77      const overmind = createOvermindMock(config, {
    78          api: mockedApi
    79      }, initialState => {
    80          Object.assign(initialState, state)
    81      });
    82      Object.assign(overmind.effects.api, mockedApi)
    83      return overmind
    84  }
    85  
    86  /** UnaryApiClient is a type that represents the ApiClient without streaming methods. */
    87  interface UnaryApiClient {
    88      client: Omit<ApiClient["client"], "submissionStream">;
    89  }
    90  
    91  /** Methods is a type that represents the methods of the UnaryApiClient */
    92  type Methods = UnaryApiClient["client"];
    93  
    94  /** mock is a helper function that takes a method and a mocked function to run in place of the method.
    95   *  It returns a function that can be used to replace the method in the ApiClient.
    96   * @param _method the method to mock
    97   * @param mockFn the function to run in place of the method
    98   * @example: mock("getSubmission", async (req) => { return { error: null, message: new Submission() } })
    99  */
   100  export function mock<T extends keyof Methods>(
   101      _method: T,
   102      mockFn: (req: Parameters<Methods[T]>[0]) => ReturnType<Methods[T]>
   103  ): Methods[T] {
   104      return async function (...args: any[]): Promise<any> {
   105          return mockFn(args);
   106      };
   107  }