@testing-library/react#within TypeScript Examples

The following examples show how to use @testing-library/react#within. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Configure.test.tsx    From twilio-voice-notification-app with Apache License 2.0 6 votes vote down vote up
selectMaterialUiSelectOption = (
  element: any,
  optionText: string
) => {
  // The the button that opens the dropdown, which is a sibling of the input
  const selectButton = element.parentNode.querySelector('[role=button]');

  // Open the select dropdown
  UserEvent.click(selectButton);

  // Get the dropdown element. We don't use getByRole() because it includes <select>s too.
  const listbox = document.body.querySelector<HTMLUListElement>(
    'ul[role=listbox]'
  );

  // Click the list item
  const listItem = within(listbox!).getByText(optionText);
  UserEvent.click(listItem);
}
Example #2
Source File: FormLayout.test.tsx    From glific-frontend with GNU Affero General Public License v3.0 6 votes vote down vote up
test('cancel button should redirect to taglist page', async () => {
  const { container, getByText } = render(
    <MockedProvider mocks={mocks} addTypename={false}>
      <Router>
        <FormLayout match={{ params: { id: 1 } }} {...defaultProps} />
        <Route path="/tag" exact component={TagList} />
      </Router>
    </MockedProvider>
  );
  await waitFor(() => {
    const { queryByText } = within(container.querySelector('form'));
    const button = queryByText('Cancel');
    fireEvent.click(button);
    expect(getByText('Loading...')).toBeInTheDocument();
  });

  await waitFor(() => {
    expect(getByText('Tags')).toBeInTheDocument();
  });
});
Example #3
Source File: SQFormDropdown.stories.test.tsx    From SQForm with MIT License 6 votes vote down vote up
it('should display an empty option when displayEmpty is true', () => {
  render(<SQFormDropdown displayEmpty size="auto" />);

  const expandButton = screen.getByRole('button', {name: /state/i});
  userEvent.click(expandButton);

  const optionsList = screen.getByRole('listbox');

  const options = within(optionsList).getAllByRole('option');
  expect(options).toHaveLength(4);
  expect(options[0]).toHaveTextContent('- -');
});
Example #4
Source File: Home.test.tsx    From office-booker with MIT License 6 votes vote down vote up
test('Selecting an office', async () => {
  const config = createFakeConfig();
  const office = createFakeOfficeWithSlots(config);
  const user = createFakeSystemAdminUser([office], { quota: 2 });
  server.use(
    mockGetConfig(config),
    mockGetOffices([office]),
    mockGetBookings([]),
    mockGetOffice(office)
  );
  render(
    <TestContext user={user}>
      <Home />
    </TestContext>
  );

  await screen.findByRole('heading', { level: 2, name: 'Select your office' });

  const main = within(screen.getByRole('main'));

  fireEvent.click(main.getByRole('button', { name: office.name }));

  await main.findByRole('heading', { level: 2, name: office.name });
  expect(main.getByText(/You can make/i)).toHaveTextContent(
    `You can make ${user.quota} booking per week`
  );
  expect(main.getByText(/daily capacity/i)).toHaveTextContent(
    `The Office has a daily capacity of ${office.quota} and car park capacity of ${office.parkingQuota}.`
  );
  expect(main.getByText(/bookings remaining/i)).toHaveTextContent(
    `${user.quota} bookings remaining`
  );

  await main.findAllByRole('button', { name: 'Book' });
});
Example #5
Source File: Footer.test.tsx    From gear-js with GNU General Public License v3.0 6 votes vote down vote up
describe('footer tests', () => {
  it('renders dot explorer link, copyright and socials', () => {
    render(<Footer />);

    const [dotLink, ...socialLinks] = screen.getAllByRole('link');

    // polkadot explorer link

    expect(dotLink).toHaveTextContent('Polkadot Explorer');
    expect(dotLink).toHaveAttribute('href', `https://polkadot.js.org/apps/?rpc=random-address#/explorer`);

    // copyright

    const copyright = screen.getByText(`${new Date().getFullYear()}. All rights reserved.`);
    expect(copyright).toBeInTheDocument();

    // socials

    const socials = screen.getByRole('list');
    const socialItems = within(socials).getAllByRole('listitem');
    const [twitter, gh, discord, medium] = socialLinks;

    expect(socialItems).toHaveLength(4);
    socialItems.forEach((item, index) => expect(item).toContainElement(socialLinks[index]));

    expect(twitter).toHaveAttribute('href', 'https://twitter.com/gear_techs');
    expect(gh).toHaveAttribute('href', 'https://github.com/gear-tech');
    expect(discord).toHaveAttribute('href', 'https://discord.com/invite/7BQznC9uD9');
    expect(medium).toHaveAttribute('href', 'https://medium.com/@gear_techs');
  });
});
Example #6
Source File: PropertyNamesSelect.test.tsx    From posthog-foss with MIT License 6 votes vote down vote up
test('Can filter properties by case insensitive substring match', async () => {
    const properties = ['Property A', 'Property B', 'Property C']

    const onChange = jest.fn()

    const { findByRole, queryByRole } = render(
        <Provider>
            <PropertyNamesSelect onChange={onChange} allProperties={properties} />
        </Provider>
    )

    const combo = await findByRole('combobox')
    const summaryText = await within(combo).findByText(/0 of 3/)
    userEvent.click(summaryText)

    await findByRole('checkbox', { name: /Property B/ })
    const searchBox = await findByRole('textbox')
    userEvent.type(searchBox, 'property a')

    await waitFor(() => expect(queryByRole('checkbox', { name: /Property B/ })).toBeNull())
})
Example #7
Source File: TaxPayerMethods.tsx    From UsTaxes with GNU Affero General Public License v3.0 5 votes vote down vote up
g = {
    foreignCountryBox: (): HTMLInputElement =>
      within(this.dom()).getByLabelText('Do you have a foreign address?')
  }
Example #8
Source File: PlanCard.test.tsx    From web3uikit with MIT License 5 votes vote down vote up
describe('PlanCard', () => {
    it('should render the render', () => {
        const { container } = render(<PlanCardStory />);
        expect(container).toBeDefined();
    });
    it('should render plan description', () => {
        const { getByText } = render(<PlanCardStory />);
        PlanCardStory.args?.description?.forEach((feature) => {
            expect(getByText(feature, { exact: false })).toBeDefined();
        });
    });
    it('should render description title', () => {
        const { getByText } = render(<PlanCardStory />);
        expect(
            getByText(`${PlanCardStory.args?.descriptionTitle}`, {
                exact: false,
            }),
        ).toBeDefined();
    });
    it('should render footer', () => {
        render(<PlanCardStory />);
        if (PlanCardStory?.args?.footer) {
            expect(
                within(PlanCardStory?.args?.footer as unknown as HTMLElement),
            ).toBeDefined();
        }
    });
    it('should render title', () => {
        render(<PlanCardStory />);
        if (PlanCardStory?.args?.title) {
            expect(
                within(PlanCardStory?.args?.title as unknown as HTMLElement),
            ).toBeDefined();
        }
    });
    it('should render your plan', () => {
        const { getByText } = render(<CurrentPlanStory />);
        expect(getByText('Your Plan', { exact: false })).toBeDefined();
    });
});
Example #9
Source File: YearsStatusBarMethods.tsx    From UsTaxes with GNU Affero General Public License v3.0 5 votes vote down vote up
getOption = (y: TaxYear): HTMLOptionElement | null =>
    (within(this.dom())
      .getAllByRole('option')
      .find((x) => x.getAttribute('value') === y) as
      | HTMLOptionElement
      | undefined) ?? null
Example #10
Source File: test-helpers.ts    From react-final-table with MIT License 5 votes vote down vote up
export function getRow<T extends RenderResult>(table: T, index: number) {
  const firstRow = table.getByTestId(`row-${index}`);
  return {
    baseElement: firstRow,
    ...within(firstRow),
  };
}
Example #11
Source File: PersonMethods.tsx    From UsTaxes with GNU Affero General Public License v3.0 5 votes vote down vote up
firstNameField = (): HTMLInputElement | null =>
    within(this.dom()).queryByLabelText(personLabels.fname)
Example #12
Source File: cookies-dialog.spec.tsx    From master-frontend-lemoncode with MIT License 5 votes vote down vote up
describe('CookiesDialog component specs', () => {
  it('should display a button with text "Learn more about our cookies"', () => {
    // Arrange
    const props = {
      onAgreeClick: () => {},
    };

    // Act
    render(<CookiesDialog {...props} />);

    const buttonElement = screen.getByRole('button', {
      name: /learn more about our cookies/i,
    });

    // Assert
    expect(buttonElement).toBeInTheDocument();
  });

  it('should open dialog when click on "Learn more about our cookies" button', () => {
    // Arrange
    const props = {
      onAgreeClick: () => {},
    };

    // Act
    render(<CookiesDialog {...props} />);

    const buttonElement = screen.getByRole('button', {
      name: /learn more about our cookies/i,
    });
    userEvent.click(buttonElement);

    const dialogElement = screen.getByRole('dialog');

    // Assert
    expect(dialogElement).toBeInTheDocument();
  });

  it('should call onAgreeClick when it clicks on "Agree" button', () => {
    // Arrange
    const props = {
      onAgreeClick: jest.fn(),
    };

    // Act
    render(<CookiesDialog {...props} />);

    // The only button available at this moment
    const buttonElement = screen.getByRole('button');
    userEvent.click(buttonElement);

    const dialogElement = screen.getByRole('dialog');

    const agreeButtonElement = within(dialogElement).getByRole('button');
    userEvent.click(agreeButtonElement);

    // Assert
    expect(props.onAgreeClick).toHaveBeenCalled();
  });
});
Example #13
Source File: SQForm.stories.test.tsx    From SQForm with MIT License 5 votes vote down vote up
describe('Tests for BasicForm', () => {
  it('renders BasicForm and calls alert on submit', async () => {
    render(<BasicForm />);

    userEvent.type(screen.getByLabelText(/first name/i), mockData.firstName);

    const {value: lastNameInputValue} = screen.getByLabelText(
      /last name/i
    ) as HTMLInputElement;
    userEvent.type(screen.getByLabelText(/hobby/i), mockData.hobby);
    userEvent.type(screen.getByLabelText(/age/i), mockData.age.toString());

    userEvent.click(screen.getByRole('button', {name: /state/i}));
    userEvent.click(screen.getByRole('option', {name: /kansas/i}));

    userEvent.click(screen.getByRole('checkbox', {name: /cool/i}));

    userEvent.click(
      within(
        screen.getByRole('group', {
          name: /cat or dog/i,
        })
      ).getByRole('radio', {name: /dog/i})
    );

    const warrantyOptions = screen.getByRole('group', {
      name: /warranty options/i,
    });
    userEvent.click(
      within(warrantyOptions).getByRole('checkbox', {name: /drivetrain/i})
    );
    userEvent.click(
      within(warrantyOptions).getByRole('checkbox', {name: /brakes/i})
    );

    userEvent.click(screen.getByRole('button', {name: /submit/i}));

    await waitFor(() =>
      expect(window.alert).toHaveBeenCalledWith(
        JSON.stringify(
          {
            firstName: mockData.firstName,
            lastName: lastNameInputValue,
            city: '',
            age: mockData.age,
            state: mockData.state,
            tenThousandOptions: '',
            note: '',
            preferredPet: mockData.preferredPet,
            warrantyOptions: mockData.warrantyOptions,
            warrantyOptionsSelectAll: false,
            favoriteColors: [2, 4],
            hobby: mockData.hobby,
            cool: mockData.cool,
            lame: false,
          },
          null,
          2
        )
      )
    );
  });

  it('shows confirmation and resets form', async () => {
    render(<BasicForm />);

    userEvent.type(screen.getByLabelText(/first name/i), mockData.firstName);

    userEvent.click(screen.getByRole('button', {name: /reset/i}));

    await screen.findByText('Reset Form');
    userEvent.click(screen.getByRole('button', {name: /reset/i}));

    await waitForElementToBeRemoved(() => screen.queryByText('Reset Form'));
    const {value: firstNameInputValue} = screen.getByLabelText(
      /first name/i
    ) as HTMLInputElement;
    expect(firstNameInputValue).toBe('');
  });
});
Example #14
Source File: Password.stories.tsx    From design-system with Apache License 2.0 5 votes vote down vote up
Revealed.play = async ({ canvasElement }) => {
	await userEvent.click(within(canvasElement).getByTestId('form.password.reveal'));
};
Example #15
Source File: SimpleStepper.test.tsx    From backstage with Apache License 2.0 5 votes vote down vote up
getTextInSlide = (rendered: any, index: number) =>
  within(rendered.getByTestId(`step${index}`)).getByText
Example #16
Source File: bountiesPage.tsx    From crust-apps with Apache License 2.0 5 votes vote down vote up
async assignCuratorButton (): Promise<HTMLElement> {
    this.assertRendered();
    const proposeCuratorModal = await this.findByTestId('propose-curator-modal');

    return await within(proposeCuratorModal).findByText('Propose curator');
  }
Example #17
Source File: JoinTeam.test.tsx    From longwave with MIT License 5 votes vote down vote up
test("Shows current team members", () => {
  const gameState: GameState = {
    ...InitialGameState(),
    players: {
      playerId: {
        name: "Player",
        team: Team.Unset,
      },
      leftTeam1: {
        name: "Left Team 1",
        team: Team.Left,
      },
      leftTeam2: {
        name: "Left Team 2",
        team: Team.Left,
      },
      rightTeam1: {
        name: "Right Team 1",
        team: Team.Right,
      },
      rightTeam2: {
        name: "Right Team 2",
        team: Team.Right,
      },
    },
  };

  const component = render(
    <TestContext gameState={gameState} playerId="player1">
      <JoinTeam />
    </TestContext>
  );

  const leftBrain = within(component.getByText("LEFT BRAIN").parentElement!);
  expect(leftBrain.getByText("Left Team 1")).toBeInTheDocument();
  expect(leftBrain.getByText("Left Team 2")).toBeInTheDocument();

  const rightBrain = within(component.getByText("RIGHT BRAIN").parentElement!);
  expect(rightBrain.getByText("Right Team 1")).toBeInTheDocument();
  expect(rightBrain.getByText("Right Team 2")).toBeInTheDocument();
});
Example #18
Source File: SpeedSend.test.tsx    From glific-frontend with GNU Affero General Public License v3.0 5 votes vote down vote up
describe('SpeedSend', () => {
  test('cancel button should redirect to SpeedSendlist page', async () => {
    const { container, getByText } = render(
      <MockedProvider mocks={mocks} addTypename={false}>
        <Router>
          <Switch>
            <Route path="/speed-send" exact component={SpeedSendList} />
          </Switch>
          <SpeedSend match={{ params: { id: 1 } }} />
        </Router>
      </MockedProvider>
    );

    await waitFor(() => {
      const { queryByText } = within(container.querySelector('form'));
      const button = queryByText('Cancel');
      fireEvent.click(button);
    });

    await waitFor(() => {
      expect(getByText('Speed sends')).toBeInTheDocument();
    });
  });

  test('save button should add a new template', async () => {
    const { container } = render(
      <MockedProvider mocks={mocks} addTypename={false}>
        <Router>
          <SpeedSend match={{ params: { id: null } }} />
          <Switch>
            <Route path="/speed-send" exact component={SpeedSendList} />
          </Switch>
        </Router>
      </MockedProvider>
    );

    await waitFor(() => {
      fireEvent.change(container.querySelector('input[name="label"]'), {
        target: { value: 'new Template' },
      });
    });

    const { queryByText } = within(container.querySelector('form'));
    await waitFor(() => {
      const button = queryByText('Save');
      fireEvent.click(button);
    });

    await waitFor(() => {
      expect(queryByText('Message is required.')).toBeInTheDocument();
      const { getByText } = within(container.querySelector('tbody'));
      expect(getByText('Good message')).toBeInTheDocument();
    });
  });
});
Example #19
Source File: FakePager.tsx    From UsTaxes with GNU Affero General Public License v3.0 5 votes vote down vote up
saveButton = (): HTMLButtonElement =>
    within(this.dom()).getByRole('button', {
      name: /Save/i
    })
Example #20
Source File: Header.test.tsx    From gear-js with GNU General Public License v3.0 4 votes vote down vote up
describe('header tests', () => {
  it('renders logo and menu', () => {
    renderWithProviders(<Header />);

    const [logo, ...menuLinks] = screen.getAllByRole('link');

    // logo

    const logoSvg = screen.getByTestId('svg');

    expect(logo).toContainElement(logoSvg);
    expect(logo).toHaveAttribute('href', '/');

    // menu

    const menu = screen.getByRole('list');
    const [, ...menuItems] = within(menu).getAllByRole('listitem'); // drop desctructuring when sidebar button won't be in menu
    const [explorer, ide, mailbox] = menuLinks;

    expect(menuItems).toHaveLength(3);

    menuItems.forEach((item, index) => {
      const link = menuLinks[index];

      expect(item).toContainElement(link);
      expect(link).not.toHaveClass(menuStyles.active);
    });

    expect(explorer).toHaveTextContent('Explorer');
    expect(explorer).toHaveAttribute('href', '/explorer');

    expect(ide).toHaveTextContent('</> IDE');
    expect(ide).toHaveAttribute('href', '/editor');

    expect(mailbox).toHaveTextContent('Mailbox');
    expect(mailbox).toHaveAttribute('href', '/mailbox');

    fireEvent.click(mailbox);
    menuLinks.forEach((link) =>
      link === mailbox ? expect(link).toHaveClass(menuStyles.active) : expect(link).not.toHaveClass(menuStyles.active)
    );

    fireEvent.click(explorer);
    menuLinks.forEach((link) =>
      link === explorer ? expect(link).toHaveClass(menuStyles.active) : expect(link).not.toHaveClass(menuStyles.active)
    );
  });

  it('renders sidebar button, opens/closes sidebar, adds/copies/removes/switches node', async () => {
    renderWithProviders(<Header />);

    // sidebar button

    const queriedSidebar = screen.queryByTestId('sidebar');
    const [sidebarButton] = screen.getAllByRole('button');

    expect(queriedSidebar).not.toBeInTheDocument();
    expect(sidebarButton).toHaveTextContent('Loading...');

    // TODO: is there a better way to mock?
    // @ts-ignore
    jest.spyOn(hooks, 'useApi').mockImplementation(() => {
      localStorage.setItem('chain', 'testnet');
      return {
        api: {
          runtimeVersion: {
            specName: {
              toHuman: () => 'test-name',
            },
            specVersion: {
              toHuman: () => '12345',
            },
          },
        },
        isApiReady: true,
      };
    });

    jest.spyOn(nodeApi, 'address', 'get').mockImplementation(() => 'testnet-address');

    await waitFor(() => {
      expect(sidebarButton).toHaveTextContent('testnet');
      expect(sidebarButton).toHaveTextContent('test-name/12345');
    });

    fireEvent.click(sidebarButton);

    const sidebar = screen.getByTestId('sidebar');
    expect(sidebar).toBeInTheDocument();

    // sidebar

    const [nodeSectionsList] = within(sidebar).getAllByRole('list');
    const [testnetSection, , , devSection] = within(nodeSectionsList).getAllByRole('listitem');

    const testnetHeading = screen.getByText('testnet heading');
    const testnetList = within(testnetSection).getByRole('list');
    const testnetItems = within(testnetList).getAllByRole('listitem');
    const testnetNodes = within(testnetList).getAllByRole('radio');

    const devHeading = screen.getByText('development');
    const devList = within(devSection).getByRole('list');
    const devItems = within(devList).getAllByRole('listitem');
    const devNodes = within(devList).getAllByRole('radio');

    expect(testnetSection).toContainElement(testnetHeading);
    expect(testnetItems).toHaveLength(2);
    testnetItems.forEach((item, index) => expect(item).toContainElement(testnetNodes[index]));

    expect(devSection).toContainElement(devHeading);
    expect(devItems).toHaveLength(1);
    devItems.forEach((item, index) => expect(item).toContainElement(devNodes[index]));

    // selects clicked node

    const randomTestnetLabel = screen.getByText('random-testnet-address');
    const [testnetNode, randomTestnetNode] = testnetNodes;

    const devLabel = screen.getByText('dev-address');
    const [devNode] = devNodes;

    const nodes = [...testnetNodes, ...devNodes];

    nodes.forEach((node) => (node === testnetNode ? expect(node).toBeChecked() : expect(node).not.toBeChecked()));

    fireEvent.click(devLabel);
    nodes.forEach((node) => (node === devNode ? expect(node).toBeChecked() : expect(node).not.toBeChecked()));

    fireEvent.click(randomTestnetLabel);
    nodes.forEach((node) => (node === randomTestnetNode ? expect(node).toBeChecked() : expect(node).not.toBeChecked()));

    // copies node address

    Object.assign(navigator, { clipboard: { writeText: jest.fn() } });
    jest.spyOn(navigator.clipboard, 'writeText');

    const copyButtons = screen.getAllByLabelText('Copy node address');
    const [, randomTestnetCopyButton, devCopyButton] = copyButtons;

    expect(copyButtons).toHaveLength(3);

    fireEvent.click(randomTestnetCopyButton);
    expect(navigator.clipboard.writeText).toBeCalledWith('random-testnet-address');

    fireEvent.click(devCopyButton);
    expect(navigator.clipboard.writeText).toBeCalledWith('dev-address');

    // validates custom address input

    const addButton = screen.getByText('Add');
    const input = screen.getByRole('textbox');

    expect(input).toHaveValue('');
    expect(addButton).toBeDisabled();

    fireEvent.change(input, { target: { value: 'wss://' } });
    expect(input).toHaveValue('wss://');
    expect(addButton).toBeDisabled();

    fireEvent.change(input, { target: { value: 'wss://test' } });
    expect(addButton).toBeEnabled();

    fireEvent.change(input, { target: { value: 'test://wss' } });
    expect(addButton).toBeDisabled();

    fireEvent.change(input, { target: { value: 'ws://custom-address' } });
    expect(addButton).not.toBeDisabled();

    // adds custom node

    fireEvent.click(addButton);
    expect(input).toHaveValue('');

    const customNodeLabel = screen.getByText('ws://custom-address');
    const customNode = screen.getByLabelText('ws://custom-address');

    expect(devList).toContainElement(customNodeLabel);
    nodes.forEach((node) => (node === randomTestnetNode ? expect(node).toBeChecked() : expect(node).not.toBeChecked()));

    fireEvent.click(customNodeLabel);
    nodes.forEach((node) => (node === customNode ? expect(node).toBeChecked() : expect(node).not.toBeChecked()));

    // removes node address

    const removeButtons = screen.getAllByLabelText('Remove node address');
    const [customNodeRemoveButton] = removeButtons;

    expect(removeButtons).toHaveLength(1);

    fireEvent.click(customNodeRemoveButton);

    expect(customNodeLabel).not.toBeInTheDocument();
    nodes.forEach((node) => (node === testnetNode ? expect(node).toBeChecked() : expect(node).not.toBeChecked()));

    // closes sidebar on close button and outside click

    const closeButton = screen.getByLabelText('Close sidebar');
    fireEvent.click(closeButton);

    expect(sidebar).not.toBeInTheDocument();

    fireEvent.click(sidebarButton);

    const newSidebar = screen.getByTestId('sidebar');
    expect(newSidebar).toBeInTheDocument();

    fireEvent.click(document);

    expect(newSidebar).not.toBeInTheDocument();

    fireEvent.click(sidebarButton);

    // switches node

    const switchButton = screen.getByText('Switch');
    expect(switchButton).toBeDisabled();

    const newRandomTestnetLabel = screen.getByText('random-testnet-address');
    fireEvent.click(newRandomTestnetLabel);

    expect(switchButton).toBeEnabled();

    // TODO: hacky mock?
    const location: Location = window.location;
    // @ts-ignore
    delete window.location;

    window.location = {
      ...location,
      reload: jest.fn(),
    };

    jest.spyOn(Storage.prototype, 'setItem').mockImplementation(() => jest.fn());

    fireEvent.click(switchButton);

    expect(window.location.reload).toHaveBeenCalledTimes(1);
    expect(localStorage.setItem).toBeCalledWith('node_address', 'random-testnet-address');
  });

  describe('account switch tests', () => {
    const getModal = () => screen.getByTestId('modal');
    const getModalQuery = () => screen.queryByTestId('modal');

    const getButtonsList = () => within(getModal()).getByRole('list');
    const getButtons = () => within(getButtonsList()).getAllByRole('button');
    const getButton = (index: number) => getButtons()[index];

    const unsubMock = jest.fn();
    const subscribeToBalanceChangeMock = jest.fn();
    const findOutBalanceMock = jest.fn();

    const apiMock = {
      api: {
        balance: { findOut: findOutBalanceMock },
        gearEvents: {
          subscribeToBalanceChange: subscribeToBalanceChangeMock,
        },
      },
    };

    const getLoginButton = () => screen.getByText('Connect');
    const getLoginButtonQuery = () => screen.queryByText('Connect');

    it('logins/logouts, switches account and closes modal', async () => {
      renderWithProviders(<Header />);

      const useApiSpy = jest.spyOn(hooks, 'useApi');
      //@ts-ignore
      useApiSpy.mockReturnValue(apiMock);
      mockedUseAccounts.mockImplementation(() => accounts);
      apiMock.api.gearEvents.subscribeToBalanceChange.mockResolvedValue(unsubMock);

      // mocking raw public key get since it gets saved in localstorage on account switch
      jest.spyOn(GearKeyring, 'decodeAddress').mockImplementation(() => '0x00');

      // logins

      fireEvent.click(getLoginButton());

      const buttons = getButtons();
      const secondButton = getButton(1);

      expect(buttons).toHaveLength(3);
      buttons.forEach((button) => expect(button).not.toHaveClass('active'));
      expect(secondButton).toHaveTextContent('second acc');
      expect(secondButton).toHaveTextContent('456');

      apiMock.api.balance.findOut.mockResolvedValue({ toHuman: () => '1000' });

      fireEvent.click(secondButton);

      const accountButton = screen.getByText('second acc');
      const balance = screen.getByText('Balance:');

      await waitFor(() => expect(balance).toHaveTextContent('Balance: 1000'));
      expect(getModalQuery()).not.toBeInTheDocument();
      expect(getLoginButtonQuery()).not.toBeInTheDocument();

      // switches

      fireEvent.click(accountButton);

      getButtons().forEach((button) =>
        button === getButton(1) ? expect(button).toHaveClass('active') : expect(button).not.toHaveClass('active')
      );

      apiMock.api.balance.findOut.mockResolvedValue({ toHuman: () => '2000' });

      fireEvent.click(getButton(2));

      await waitFor(() => expect(balance).toHaveTextContent('Balance: 2000'));
      expect(getModalQuery()).not.toBeInTheDocument();
      expect(accountButton).toHaveTextContent('third acc');

      fireEvent.click(accountButton);

      getButtons().forEach((button) =>
        button === getButton(2) ? expect(button).toHaveClass('active') : expect(button).not.toHaveClass('active')
      );

      // logouts

      const logoutButton = screen.getByLabelText('Logout');

      fireEvent.click(logoutButton);

      expect(getModalQuery()).not.toBeInTheDocument();
      expect(balance).not.toBeInTheDocument();
      expect(accountButton).not.toBeInTheDocument();

      fireEvent.click(getLoginButton());

      getButtons().forEach((button) => expect(button).not.toHaveClass('active'));

      // closes modal

      const closeModalButton = screen.getByLabelText('Close modal');

      fireEvent.click(closeModalButton);
      expect(getModalQuery()).not.toBeInTheDocument();

      // balance subscription

      expect(subscribeToBalanceChangeMock).toBeCalledTimes(2);
      await waitFor(() => expect(unsubMock).toBeCalledTimes(2));
    });

    it('logins without extension', () => {
      renderWithProviders(<Header />);

      fireEvent.click(getLoginButton());

      const noExtensionMessage = screen.getByText(
        textMatcher('Polkadot extension was not found or disabled. Please install it')
      );

      expect(getModal()).toContainElement(noExtensionMessage);
    });

    it('logins without accounts', () => {
      renderWithProviders(<Header />);
      mockedUseAccounts.mockImplementation(() => []);

      fireEvent.click(getLoginButton());

      const noAccountsMessage = screen.getByText(
        'No accounts found. Please open your Polkadot extension and create a new account or import existing. Then reload this page.'
      );

      expect(getModal()).toContainElement(noAccountsMessage);
    });
  });
});
Example #21
Source File: TechDocsSearch.test.tsx    From backstage with Apache License 2.0 4 votes vote down vote up
describe('<TechDocsSearch />', () => {
  it('should render techdocs search bar', async () => {
    const query = () => emptyResults;
    const querySpy = jest.fn(query);
    const searchApi = { query: querySpy };

    const apiRegistry = TestApiRegistry.from([searchApiRef, searchApi]);

    await act(async () => {
      const rendered = render(
        wrapInTestApp(
          <ApiProvider apis={apiRegistry}>
            <TechDocsSearch entityId={entityId} />
          </ApiProvider>,
        ),
      );

      await emptyResults;
      expect(querySpy).toBeCalled();
      expect(rendered.getByTestId('techdocs-search-bar')).toBeInTheDocument();
    });
  });

  it('should trigger query when autocomplete input changed', async () => {
    const query = () => singleResult;
    const querySpy = jest.fn(query);
    const searchApi = { query: querySpy };

    const apiRegistry = TestApiRegistry.from([searchApiRef, searchApi]);

    await act(async () => {
      const rendered = render(
        wrapInTestApp(
          <ApiProvider apis={apiRegistry}>
            <TechDocsSearch entityId={entityId} debounceTime={0} />
          </ApiProvider>,
        ),
      );

      await singleResult;
      expect(querySpy).toBeCalledWith({
        filters: {
          kind: 'Testable',
          name: 'test',
          namespace: 'testspace',
        },
        pageCursor: '',
        term: '',
        types: ['techdocs'],
      });

      const autocomplete = rendered.getByTestId('techdocs-search-bar');
      const input = within(autocomplete).getByRole('textbox');
      autocomplete.click();
      autocomplete.focus();
      fireEvent.change(input, { target: { value: 'asdf' } });

      await singleResult;
      await waitFor(() =>
        expect(querySpy).toBeCalledWith({
          filters: {
            kind: 'Testable',
            name: 'test',
            namespace: 'testspace',
          },
          pageCursor: '',
          term: 'asdf',
          types: ['techdocs'],
        }),
      );
    });
  });

  it('should update filter values when a new entityName is provided', async () => {
    const query = () => singleResult;
    const querySpy = jest.fn(query);
    const searchApi = { query: querySpy };
    const apiRegistry = TestApiRegistry.from([searchApiRef, searchApi]);
    const newEntityId = {
      name: 'test-diff',
      namespace: 'testspace-diff',
      kind: 'TestableDiff',
    };

    const WrappedSearchBar = () => {
      const [entityName, setEntityName] = useState(entityId);
      return wrapInTestApp(
        <ApiProvider apis={apiRegistry}>
          <button onClick={() => setEntityName(newEntityId)}>
            Update Entity
          </button>
          <TechDocsSearch entityId={entityName} debounceTime={0} />
        </ApiProvider>,
      );
    };

    await act(async () => {
      const rendered = render(<WrappedSearchBar />);

      await singleResult;
      expect(querySpy).toBeCalledWith({
        filters: {
          kind: 'Testable',
          name: 'test',
          namespace: 'testspace',
        },
        pageCursor: '',
        term: '',
        types: ['techdocs'],
      });

      const button = rendered.getByText('Update Entity');
      button.click();

      await singleResult;
      await waitFor(() =>
        expect(querySpy).toBeCalledWith({
          filters: {
            kind: 'TestableDiff',
            name: 'test-diff',
            namespace: 'testspace-diff',
          },
          pageCursor: '',
          term: '',
          types: ['techdocs'],
        }),
      );
    });
  });
});
Example #22
Source File: MyAccount.test.tsx    From glific-frontend with GNU Affero General Public License v3.0 4 votes vote down vote up
describe('<MyAccount />', () => {
  test('it should render', async () => {
    const { getByText, findByTestId } = render(wrapper);

    // loading is show initially
    expect(getByText('Loading...')).toBeInTheDocument();

    const myAccount = await findByTestId('MyAccount');
    expect(myAccount).toHaveTextContent('Change Password');
  });

  test('generate OTP success flow', async () => {
    const { container } = render(wrapper);

    // let's mock successful sending of OTP
    const responseData = { data: { data: { data: {} } } };
    axios.post.mockImplementationOnce(() => Promise.resolve(responseData));

    await waitFor(() => {
      // click on generate OTP
      const generateOTPButton = screen.getByText('Generate OTP');
      UserEvent.click(generateOTPButton);
    });

    // set the mock
    const resendPasswordResponse = {
      data: { message: 'OTP sent successfully to 919967665667', phone: '919967665667' },
    };
    axios.post.mockImplementationOnce(() => Promise.resolve(resendPasswordResponse));

    await waitFor(() => {
      // click on resend button
      const resendButton = screen.getByTestId('resendOtp');
      UserEvent.click(resendButton);
    });

    // trigger validation errors
    await waitFor(() => {
      // click on save button
      const saveButton = screen.getByText('Save');
      UserEvent.click(saveButton);
    });

    // check for validation errors
    await waitFor(() => {
      expect(screen.getAllByText('Input required')).toHaveLength(2);
    });

    const dropdown = screen.getByTestId('dropdown');
    const { getByRole } = within(dropdown);
    const inputDropdown = getByRole('button');
    fireEvent.mouseDown(inputDropdown);
    const [english, hindi] = screen.getAllByRole('option');
    hindi.click();

    // enter otp
    const input = container.querySelector('input[type="text"]');
    UserEvent.type(input, '76554');

    // enter password
    const password = container.querySelector('input[type="password"]');
    UserEvent.type(password, 'pass123456');

    await waitFor(() => {
      // view password
      const passwordToggle = screen.getByTestId('passwordToggle');
      UserEvent.click(passwordToggle);

      // click on save button
      const saveButton = screen.getByText('Save');
      UserEvent.click(saveButton);
    });

    // assert successful save
    // await waitFor(() => {
    //   expect(screen.getByText('Password updated successfully!')).toBeInTheDocument();
    // });
  });

  test('generate OTP error response', async () => {
    const { findByTestId } = render(wrapper);

    // let's mock error case sending of OTP
    const errorMessage = 'Cannot register 919967665667';
    axios.post.mockImplementationOnce(() => Promise.reject(new Error(errorMessage)));

    await waitFor(() => {
      // click on generate OTP
      const generateOTPButton = screen.getByText('Generate OTP');
      UserEvent.click(generateOTPButton);
    });

    // close the alert
    const closeAlert = await findByTestId('crossIcon');
    UserEvent.click(closeAlert);
  });

  test('generate OTP success flow with cancel', async () => {
    render(wrapper);

    // let's mock successful sending of OTP
    const responseData = { data: { data: { data: {} } } };
    axios.post.mockImplementationOnce(() => Promise.resolve(responseData));

    await waitFor(() => {
      // click on generate OTP
      const generateOTPButton = screen.getByText('Generate OTP');
      UserEvent.click(generateOTPButton);
    });

    // click on CANCEL button
    const cancelButton = screen.getByText('Cancel');
    UserEvent.click(cancelButton);
  });

  test('generate OTP error with incorrect OTP', async () => {
    const { container } = render(wrapper);

    // let's mock successful sending of OTP
    const responseData = { data: { data: { data: {} } } };
    axios.post.mockImplementationOnce(() => Promise.resolve(responseData));

    await waitFor(() => {
      // click on generate OTP
      const generateOTPButton = screen.getByText('Generate OTP');
      UserEvent.click(generateOTPButton);
    });

    // enter otp
    const input = container.querySelector('input[type="text"]');
    UserEvent.type(input, '1234');

    // enter password
    const password = container.querySelector('input[type="password"]');
    UserEvent.type(password, 'pass123456');
    await waitFor(() => {
      // click on save button
      const saveButton = screen.getByText('Save');
      UserEvent.click(saveButton);
    });

    // assert for incorrect OTP
    // await waitFor(() => {
    //   expect(screen.getByText('Please enter a valid OTP')).toBeInTheDocument();
    // });
  });

  test('generate OTP error with too many attempts', async () => {
    const { container } = render(wrapper);

    // let's mock successful sending of OTP
    const responseData = { data: { data: { data: {} } } };
    axios.post.mockImplementationOnce(() => Promise.resolve(responseData));

    await waitFor(() => {
      // click on generate OTP
      const generateOTPButton = screen.getByText('Generate OTP');
      UserEvent.click(generateOTPButton);
    });

    // enter otp
    const input = container.querySelector('input[type="text"]');
    UserEvent.type(input, '4567');

    // enter password
    const password = container.querySelector('input[type="password"]');
    UserEvent.type(password, 'pass123456');

    await waitFor(() => {
      // click on save button
      const saveButton = screen.getByText('Save');
      UserEvent.click(saveButton);
    });
  });
});
Example #23
Source File: SQFormMultiSelect.stories.test.tsx    From SQForm with MIT License 4 votes vote down vote up
describe('Tests for SQFormMultiSelect', () => {
  it('should render a form with a multiselect input', async () => {
    render(<SQFormMultiSelect size="auto" />);

    const expandButton = await screen.findByRole('button', {
      name: /friends/i,
    });

    userEvent.click(expandButton);

    const optionsList = screen.getByRole('listbox');
    expect(optionsList).toBeInTheDocument();

    const options = within(optionsList).getAllByRole('option');
    expect(options).toHaveLength(17); // initial '- -' + 16 MOCK_FRIENDS_OPTIONS
  });

  it('should render dropdown options', async () => {
    render(<SQFormMultiSelect size="auto" />);

    const expandButton = await screen.findByRole('button', {
      name: /friends/i,
    });

    userEvent.click(expandButton);

    const optionsList = screen.getByRole('listbox');
    const options = within(optionsList).getAllByRole('option');
    expect(options).toHaveLength(17); // initial '- -' + 16 MOCK_FRIENDS_OPTIONS
  });

  it('should render the multiselect with default initial value "- -"', async () => {
    render(<SQFormMultiSelect size="auto" />);

    const expandButton = await screen.findByRole('button', {name: /friends/i});

    expect(expandButton).toHaveTextContent(initialDropdownValue);
  });

  it('should render the multiselect with the correct options selected according to initialValues', async () => {
    const initialValueLabels = 'Joe, Jane';

    render(
      <SQFormMultiSelect
        size="auto"
        sqFormProps={{
          initialValues: {friends: [1, 2]},
        }}
      />
    );

    const expandButton = await screen.findByRole('button', {name: /friends/i});

    expect(expandButton).toHaveTextContent(initialValueLabels);
  });

  it('should show console warning if provided initial value not in options', async () => {
    const consoleWarnSpy = jest
      .spyOn(console, 'warn')
      .mockImplementation(() => {
        /* do nothing */
      });

    render(
      <SQFormMultiSelect
        size="auto"
        sqFormProps={{
          initialValues: {friends: [0]},
        }}
      />
    );

    await waitFor(() =>
      expect(consoleWarnSpy).toHaveBeenCalledWith(
        expect.stringMatching(
          /the requested display value.*could not be found/i
        )
      )
    );

    consoleWarnSpy.mockRestore();
  });

  it('should show empty list if no options passed', async () => {
    render(
      <SQFormMultiSelect useSelectAll={false} size="auto" children={[]} />
    );

    const expandButton = await screen.findByRole('button', {name: /friends/i});

    userEvent.click(expandButton);
    expect(screen.queryByRole('option')).not.toBeInTheDocument();
  });

  it('should update when options are selected', async () => {
    render(<SQFormMultiSelect size="auto" />);

    const expandButton = await screen.findByRole('button', {name: /friends/i});

    expect(expandButton).toHaveTextContent(initialDropdownValue);

    userEvent.click(expandButton);

    const option1 = screen.getByText('Jack');
    userEvent.click(option1);

    const option2 = screen.getByText('Jill');
    userEvent.click(option2);

    await waitFor(() => expect(expandButton).toHaveTextContent('Jack, Jill'));
  });

  it('should not open dropdown options if field is disabled', async () => {
    render(<SQFormMultiSelect size="auto" isDisabled={true} />);

    const expandButton = await screen.findByRole('button', {name: /friends/i});
    expect(expandButton).toHaveAttribute('aria-disabled', 'true');

    const optionsList = screen.queryByRole('listbox');
    expect(optionsList).not.toBeInTheDocument();
  });

  it('should initially render "required" helper text if field is required', async () => {
    render(<SQFormMultiSelectWithValidation size="auto" />);

    await waitFor(() => expect(screen.getByText(/required/i)).toBeVisible());
  });

  it('should not display "required" helper text if field is not required', async () => {
    render(<SQFormMultiSelect size="auto" />);

    await screen.findByText('Friends');

    const required = screen.queryByText(/required/i);
    expect(required).not.toBeInTheDocument();
  });
});