import { Page } from 'playwright';
import { WidgetHelper } from './WidgetHelper';
import { test as base } from '@playwright/test';
import { GlobalAlert, Header } from './layout';
import { login } from './api/request';

import { Actions } from './actions';

const initWidgetHelper = (page: Page) => new WidgetHelper(page);

async function chain<T>(...steps: (() => Promise<any> | any)[]): Promise<T> {
  let result: any;
  for (const step of steps) {
    result = await step();
  }
  return result as T;
}

export type TestExtended = {
  widgetHelper: ReturnType<typeof initWidgetHelper>;
  layoutHeper: {
    globalAlert: GlobalAlert;
    header: Header;
  };
  chain: typeof chain;
  actions: {
    loginAsUser: (login: string, password?: string) => Promise<void>;
    logOut: () => Promise<void>;
  };
  api: {
    login: () => Promise<void>;
  };
  step: () => void;
};

export const test = base.extend<TestExtended>({
  widgetHelper: async ({ page }, use) => {
    await use(initWidgetHelper(page));
  },
  layoutHeper: async ({ page }, use) => {
    await use({
      globalAlert: new GlobalAlert(page),
      header: new Header(page),
    });
  },
  actions: async ({ page }, use) => {
    await use({
      loginAsUser: async (login: string, pass?: string) =>
        await Actions.loginAsUser(page, login, pass),
      logOut: async () => await Actions.logOut(page),
    });
  },
  api: async ({}, use) => {
    await use({ login });
  },
});

export const expect = test.expect;
