@testing-library/react#getByTestId TypeScript Examples

The following examples show how to use @testing-library/react#getByTestId. 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: join-multiple.spec.tsx    From engine with MIT License 6 votes vote down vote up
test("should support join() with multiple views and producers", (done) => {
  const fooValue = "123";
  const rootEl = document.createElement("div");
  rootEl.setAttribute("id", "root");
  document.body.appendChild(rootEl);
  const A: view = ({ foo, bar = get.bar }) => {
    expect(foo).toBe(fooValue);
    return <div data-testid="bar">{bar.value()}</div>;
  };
  const B: view = ({ foo, baz = get.baz }) => {
    return <div data-testid="baz">{baz.value()}</div>;
  };
  const p1: producer = ({ foo, bar = update.bar }) => {
    expect(foo).toBe(fooValue);
    bar.set(foo);
  };
  const p2: producer = ({ foo, baz = update.baz }) => {
    baz.set(foo);
  };

  const Component = join(A, B, p1, p2);

  const app = engine({
    use: [render(<Component foo={fooValue} />, rootEl)],
  });

  app.start();

  flushPromises();
  jest.runAllTimers();
  flushPromises();
  waitFor(() => getByTestId(document.body, "bar")).then((x) => {
    expect(x.innerHTML).toBe(fooValue);
    waitFor(() => getByTestId(document.body, "baz")).then((x) => {
      expect(x.innerHTML).toBe(fooValue);
      done();
    });
  });
});
Example #2
Source File: stateChange.spec.tsx    From engine with MIT License 6 votes vote down vote up
test("Simple load of a react component and work with producers", async (done) => {
  const defaultState = {};
  const val = "321";
  const rootEl = document.createElement("div");
  rootEl.setAttribute("id", "root");
  document.body.appendChild(rootEl);
  const Component: view = ({ bam = observe.bam, baz = update.baz }) => {
    return (
      <div>
        <div data-testid="foo" onClick={() => baz.set(val)}></div>;
        <div data-testid="bam">{bam}</div>;
      </div>
    );
  };
  const prod: producer = ({ baz = observe.baz, bam = update.bam }) => {
    bam.set(baz);
  };

  const app = engine({
    state: defaultState,
    use: [render(<Component />, rootEl), producers([prod])],
  });

  app.start();

  jest.runAllTimers();
  await flushPromises();
  waitFor(() => getByTestId(document.body, "foo")).then(async (x) => {
    fireEvent.click(x);
    jest.runAllTimers();
    await flushPromises();
    waitFor(() => getByTestId(document.body, "bam")).then((y) => {
      expect(y.innerHTML).toBe(val);
      done();
    });
  });
});
Example #3
Source File: wildcard.spec.tsx    From engine with MIT License 6 votes vote down vote up
test.skip("should support wildcard", async (done) => {
  const defaultState = {};
  const rootEl = document.createElement("div");
  rootEl.setAttribute("id", "root");
  document.body.appendChild(rootEl);
  const Component: view = ({
    id = wildcard,
    name = observe.foo[arg.id].name,
  }) => {
    return (
      <div data-testid="foo" data-id={id}>
        {name}
      </div>
    );
  };
  const fooUpdater: producer = ({ value = update.foo.xyz.name }) => {
    value.set("321");
  };

  const app = engine({
    state: defaultState,
    use: [render(<Component />, rootEl), producers([fooUpdater])],
  });

  app.start();

  jest.runAllTimers();
  await flushPromises();
  waitFor(() => getByTestId(document.body, "foo")).then((x) => {
    expect(x.innerHTML).toBe("321");
    expect(x.getAttribute("data-id")).toBe("xyz");
    done();
  });
});
Example #4
Source File: adaptor.spec.tsx    From engine with MIT License 6 votes vote down vote up
test("should support adaptor functionality", (done) => {
  const rootEl = document.createElement("div");
  rootEl.setAttribute("id", "root");
  document.body.appendChild(rootEl);
  const Component: view = ({ value = observe[prop.name] }) => {
    return <div data-testid="foo">{value}</div>;
  };
  const App = adaptor(Component, {}, { state: { foo: 123 } });

  const Component2 = () => {
    return (
      <div>
        <App name="foo" />
      </div>
    );
  };
  ReactDOM.render(<Component2 />, rootEl);
  jest.runAllTimers();
  waitFor(() => getByTestId(document.body, "foo")).then((x) => {
    expect(parseInt(x.innerHTML)).toBe(123);
    done();
  });
});
Example #5
Source File: path.spec.tsx    From engine with MIT License 6 votes vote down vote up
test("should support path operations", async (done) => {
  const defaultState = {
    items: {
      foo: {
        bar: {
          value: "123",
        },
      },
    },
  };
  const rootEl = document.createElement("div");
  rootEl.setAttribute("id", "root");
  document.body.appendChild(rootEl);
  const path1 = path.items.foo;
  const path2 = path.bar;
  const Component: view = ({
    path2,
    value = observe[path1][prop.path2].value,
  }) => {
    return <div data-testid="foo">{value}</div>;
  };

  const app = engine({
    state: defaultState,
    use: [render(<Component path2={path2} />, rootEl)],
  });

  app.start();

  jest.runAllTimers();
  await flushPromises();
  waitFor(() => getByTestId(document.body, "foo")).then((x) => {
    expect(x.innerHTML).toBe(defaultState.items.foo.bar.value);
    done();
  });
});
Example #6
Source File: get.spec.tsx    From engine with MIT License 6 votes vote down vote up
test("Expect to call using only get", async (done) => {
  const defaultState = {
    foo: "123",
  };
  const rootEl = document.createElement("div");
  rootEl.setAttribute("id", "root");
  document.body.appendChild(rootEl);
  const Component: view = ({ foo = get.foo }) => {
    expect(foo).toBeDefined();
    return <div data-testid="foo">{foo.value()}</div>;
  };

  const app = engine({
    state: defaultState,
    use: [render(<Component />, rootEl)],
  });

  app.start();

  jest.runAllTimers();
  await flushPromises();
  waitFor(() => getByTestId(document.body, "foo")).then((x) => {
    expect(x.innerHTML).toBe(defaultState.foo);
    done();
  });
});
Example #7
Source File: UMLEditor.test.tsx    From legend-studio with Apache License 2.0 6 votes vote down vote up
test(integrationTest('Profile editor renders properly'), async () => {
  await TEST__openElementFromExplorerTree(
    'ui::test1::ProfileTest',
    renderResult,
  );
  const editPanelHeader = renderResult.getByTestId(
    LEGEND_STUDIO_TEST_ID.EDIT_PANEL__HEADER_TABS,
  );
  expect(getByText(editPanelHeader, 'ProfileTest')).not.toBeNull();
  const editPanelContent = renderResult.getByTestId(
    LEGEND_STUDIO_TEST_ID.EDIT_PANEL_CONTENT,
  );
  expect(getByText(editPanelContent, 'ProfileTest')).not.toBeNull();
  const taggedValues = ['tag1', 'tag2', 'tag3'];
  taggedValues.forEach((t) =>
    expect(getByDisplayValue(editPanelContent, t)).not.toBeNull(),
  );
  fireEvent.click(getByText(editPanelContent, 'Stereotypes'));
  const stereotypes = ['stereotype1', 'stereotype2'];
  stereotypes.forEach((s) =>
    expect(getByDisplayValue(editPanelContent, s)).not.toBeNull(),
  );
});
Example #8
Source File: empty.spec.tsx    From engine with MIT License 6 votes vote down vote up
test("should load an empty component", async (done) => {
  const defaultState = {};
  const rootEl = document.createElement("div");
  rootEl.setAttribute("id", "root");
  document.body.appendChild(rootEl);
  const Component: view = () => {
    return <div data-testid="foo">foo</div>;
  };
  const app = engine({
    state: defaultState,
    use: [render(<Component />, rootEl)],
  });

  app.start();

  jest.runAllTimers();
  await flushPromises();
  waitFor(() => getByTestId(document.body, "foo")).then((x) => {
    expect(x.innerHTML).toBe("foo");
    done();
  });
});
Example #9
Source File: UMLEditor.test.tsx    From legend-studio with Apache License 2.0 6 votes vote down vote up
test(integrationTest('Enumeration editor'), async () => {
  await TEST__openElementFromExplorerTree('ui::TestEnumeration', renderResult);
  const editPanelHeader = renderResult.getByTestId(
    LEGEND_STUDIO_TEST_ID.EDIT_PANEL__HEADER_TABS,
  );
  expect(getByText(editPanelHeader, 'TestEnumeration')).not.toBeNull();
  const enumerationEditor = renderResult.getByTestId(
    LEGEND_STUDIO_TEST_ID.ENUMERATION_EDITOR,
  );
  const enums = ['enumA', 'enumB', 'enumC'];
  enums.forEach((e) => getByDisplayValue(enumerationEditor, e));
  fireEvent.click(getByText(enumerationEditor, 'Tagged Values'));
  await waitFor(() => getByText(enumerationEditor, 'ProfileTest'));
  getByDisplayValue(enumerationEditor, 'Enumeration Tag');
  fireEvent.click(getByText(enumerationEditor, 'Stereotypes'));
  await waitFor(() => getByText(enumerationEditor, 'stereotype2'));
  fireEvent.click(getByText(enumerationEditor, 'Values'));
  await waitFor(() => getByDisplayValue(enumerationEditor, 'enumA'));
  const enumB = getByDisplayValue(enumerationEditor, 'enumA');
  const parentElement = enumB.parentElement?.parentElement as HTMLElement;
  const buttons = queryAllByRole(parentElement, 'button');
  expect(buttons).toHaveLength(2);
  fireEvent.click(guaranteeNonNullable(buttons[0])); // navigate
  await waitFor(() => getByText(enumerationEditor, 'enum'));
  const subPropertyPanel = getByTestId(
    enumerationEditor,
    LEGEND_STUDIO_TEST_ID.PANEL,
  );
  getByDisplayValue(subPropertyPanel, 'enumATag');
  fireEvent.click(getByText(subPropertyPanel, 'Stereotypes'));
  await waitFor(() => getByText(subPropertyPanel, 'stereotype1'));
  fireEvent.click(
    guaranteeNonNullable(queryAllByRole(subPropertyPanel, 'button')[0]),
  );
  fireEvent.click(guaranteeNonNullable(buttons[1])); // delete
  expect(queryByText(enumerationEditor, 'enumA')).toBeNull();
});
Example #10
Source File: basic.spec.tsx    From engine with MIT License 6 votes vote down vote up
test("Simple load of a react component", async (done) => {
  const defaultState = {
    foo: "123",
  };
  const rootEl = document.createElement("div");
  rootEl.setAttribute("id", "root");
  document.body.appendChild(rootEl);
  const Component: view = ({ foo = observe.foo }) => {
    return <div data-testid="foo">{foo}</div>;
  };

  expect(Component.displayName).not.toBeUndefined();

  const app = engine({
    state: defaultState,
    use: [render(<Component />, rootEl)],
  });

  app.start();

  jest.runAllTimers();
  await flushPromises();
  waitFor(() => getByTestId(document.body, "foo")).then((x) => {
    expect(x.innerHTML).toBe(defaultState.foo);
    done();
  });
});
Example #11
Source File: viewSelector-singleHierarchy.spec.tsx    From engine with MIT License 6 votes vote down vote up
test("should support viewSelector() with a single hierarchy", async (done) => {
  const rootEl = document.createElement("div");
  rootEl.setAttribute("id", "root");
  document.body.appendChild(rootEl);

  enum Ids {
    A = "a",
  }

  const A: view = () => <div data-testid={Ids.A}>{Ids.A}</div>;

  const selector = (data) => {
    return Ids.A;
  };

  const Component = viewSelector(
    {
      [Ids.A]: A,
    },
    selector
  );

  const app = engine({
    use: [render(<Component />, rootEl)],
  });

  app.start();

  jest.runAllTimers();
  await flushPromises();
  waitFor(() => getByTestId(document.body, Ids.A)).then(async (x) => {
    expect(x.innerHTML).toBe(Ids.A);
    done();
  });
});
Example #12
Source File: join-simple.spec.tsx    From engine with MIT License 6 votes vote down vote up
test("should support join() with a single view", async (done) => {
  const rootEl = document.createElement("div");
  rootEl.setAttribute("id", "root");
  document.body.appendChild(rootEl);
  const A: view = () => <div data-testid="a">a</div>;
  const Component = join(A);
  const app = engine({
    use: [render(<Component />, rootEl)],
  });
  app.start();
  waitFor(() => getByTestId(document.body, "a")).then((x) => {
    expect(x.innerHTML).toBe("a");
    done();
  });
});
Example #13
Source File: join-reactComponentWithProducers.spec.tsx    From engine with MIT License 6 votes vote down vote up
test("should support join() with a react component with producers", async (done) => {
  const rootEl = document.createElement("div");
  rootEl.setAttribute("id", "root");
  document.body.appendChild(rootEl);
  const A = () => <div data-testid="a">a</div>;
  let _foo;
  const b: producer = ({ foo = observe.foo }) => {
    _foo = foo;
  };
  const Component = join(A, b);
  const app = engine({
    state: {
      foo: 123,
    },
    use: [render(<Component />, rootEl)],
  });
  app.start();
  waitFor(() => getByTestId(document.body, "a")).then((x) => {
    expect(x.innerHTML).toBe("a");
    expect(_foo).toBe(123);
    done();
  });
});
Example #14
Source File: join-multipleReactComponents.spec.tsx    From engine with MIT License 6 votes vote down vote up
test("should support join() with multiple react components", async (done) => {
  const rootEl = document.createElement("div");
  rootEl.setAttribute("id", "root");
  document.body.appendChild(rootEl);
  const A = ({ value }) => <div data-testid="a">{value}</div>;
  const B = ({ value }) => <div data-testid="b">{value}</div>;
  const Component = join(A, B);
  const app = engine({
    state: {
      foo: 123,
    },
    use: [render(<Component value="123" />, rootEl)],
  });
  app.start();
  waitFor(() => getByTestId(document.body, "a")).then((x) => {
    expect(x.innerHTML).toBe("123");
    waitFor(() => getByTestId(document.body, "b")).then((x) => {
      expect(x.innerHTML).toBe("123");
      done();
    });
  });
});
Example #15
Source File: UMLEditor.test.tsx    From legend-studio with Apache License 2.0 5 votes vote down vote up
test(integrationTest('Association editor'), async () => {
  await TEST__openElementFromExplorerTree('ui::TestAssociation', renderResult);
  const editPanelHeader = renderResult.getByTestId(
    LEGEND_STUDIO_TEST_ID.EDIT_PANEL__HEADER_TABS,
  );
  expect(getByText(editPanelHeader, 'TestAssociation')).not.toBeNull();
  const associationEditor = renderResult.getByTestId(
    LEGEND_STUDIO_TEST_ID.ASSOCIATION_EDITOR,
  );
  const properties = ['testClassProp', 'testClassSibling'];
  // input fields for association property name are present
  properties.forEach((t) =>
    expect(getByDisplayValue(associationEditor, t)).not.toBeNull(),
  );
  // Tagged Values
  fireEvent.click(getByText(associationEditor, 'Tagged Values'));
  await waitFor(() => getByText(associationEditor, 'ProfileTest'));
  getByDisplayValue(associationEditor, 'Association Tag');
  // Steretypes
  fireEvent.click(getByText(associationEditor, 'Stereotypes'));
  await waitFor(() => getByText(associationEditor, 'stereotype2'));
  // Back to properties
  fireEvent.click(getByText(associationEditor, 'Properties'));
  await waitFor(() => getByDisplayValue(associationEditor, 'testClassProp'));
  const inputA = getByDisplayValue(associationEditor, 'testClassProp');
  const propertyTypeA = inputA.parentElement?.parentElement
    ?.parentElement as HTMLElement;
  fireEvent.change(inputA, { target: { value: 'random' } });
  await waitFor(() => getByDisplayValue(associationEditor, 'random'));
  expect(getAllByDisplayValue(propertyTypeA, '1')).toHaveLength(2);
  expect(getByText(propertyTypeA, 'TestClass')).not.toBeNull();
  expect(getAllByRole(propertyTypeA, 'button')).toHaveLength(2);
  // sub panel property
  const inputB = getByDisplayValue(associationEditor, 'testClassSibling');
  const propertyTypeB = inputB.parentElement?.parentElement
    ?.parentElement as HTMLElement;
  const buttons = getAllByRole(propertyTypeB, 'button');
  expect(buttons).toHaveLength(2);
  expect(queryByDisplayValue(associationEditor, 'ProfileTest')).toBeNull();
  fireEvent.click(guaranteeNonNullable(buttons[1])); // navigate
  const subPropertyPanel = getByTestId(
    associationEditor,
    LEGEND_STUDIO_TEST_ID.PANEL,
  );
  getByDisplayValue(subPropertyPanel, 'association tag');
  fireEvent.click(getByText(subPropertyPanel, 'Stereotypes'));
  await waitFor(() => getByText(subPropertyPanel, 'stereotype1'));
  fireEvent.click(
    guaranteeNonNullable(queryAllByRole(subPropertyPanel, 'button')[0]),
  );
});
Example #16
Source File: App.test.tsx    From ant-simple-draw with MIT License 5 votes vote down vote up
describe('<App />', () => {
  it('renders without errors', () => {
    const { container } = render(<App />);
    // a标签含有data-testid='aNoDisabled',进行检查
    expect(getByTestId(container, 'aNoDisabled')).not.toBeDisabled();
  });
});
Example #17
Source File: EditPanel.test.tsx    From legend-studio with Apache License 2.0 5 votes vote down vote up
test(integrationTest('Test navigation between element states'), async () => {
  // Test opening multiple elements
  await TEST__openElementFromExplorerTree('ui::test1::Animal', renderResult);
  const packageExplorer = renderResult.getByTestId(
    LEGEND_STUDIO_TEST_ID.EXPLORER_TREES,
  );
  fireEvent.click(getByText(packageExplorer, 'TestClass'));
  fireEvent.click(getByText(packageExplorer, 'TestEnumeration'));
  fireEvent.click(getByText(packageExplorer, 'Anyone'));
  fireEvent.click(getByText(packageExplorer, 'Dog'));
  fireEvent.click(getByText(packageExplorer, 'Something'));
  fireEvent.click(getByText(packageExplorer, 'ProfileTest'));
  const editPanelHeader = renderResult.getByTestId(
    LEGEND_STUDIO_TEST_ID.EDIT_PANEL__HEADER_TABS,
  );
  await waitFor(() => getByText(editPanelHeader, 'ProfileTest'));

  const openElements = [
    'TestEnumeration',
    'TestClass',
    'Anyone',
    'Dog',
    'Something',
    'ProfileTest',
  ];
  openElements.forEach((openEl) => getByText(editPanelHeader, openEl));

  // navigate through visit buttons
  fireEvent.click(getByText(editPanelHeader, 'TestClass'));
  await waitFor(() => renderResult.getByText('founder'));
  const navigateToClass = async (className: string): Promise<void> => {
    const classForm = renderResult.getByTestId(
      LEGEND_STUDIO_TEST_ID.CLASS_FORM_EDITOR,
    );
    const property = await waitFor(() => getByText(classForm, className));
    const propertyBasicEditor = property.parentElement as HTMLElement;
    const navigateButton = getByTestId(
      propertyBasicEditor,
      LEGEND_STUDIO_TEST_ID.TYPE_VISIT,
    );
    fireEvent.click(navigateButton);
    await waitFor(() => getByText(editPanelHeader, className));
  };

  await navigateToClass('Person');
  await navigateToClass('Firm');
  await navigateToClass('Person');
  await navigateToClass('Degree');
  const newOpened = ['Firm', 'Degree', 'Person'];
  openElements
    .concat(newOpened)
    .forEach((openElement) => getByText(editPanelHeader, openElement));

  // test closing of tabs
  const closeTabs = ['Firm', 'Degree', 'TestEnumeration'];
  closeTabs.forEach((tab) => {
    const text = getByText(editPanelHeader, tab);
    const parent = text.parentElement as HTMLElement;
    const deleteButton = getByTitle(parent, 'Close');
    fireEvent.click(deleteButton);
  });
  closeTabs.forEach((tab) =>
    expect(queryByText(editPanelHeader, tab)).toBeNull(),
  );
  // TODO Add Diff Element States
});
Example #18
Source File: privateProps.spec.tsx    From engine with MIT License 5 votes vote down vote up
test("should provide private helper props", async (done) => {
  const defaultState = {
    foo: "123",
  };
  const rootEl = document.createElement("div");
  rootEl.setAttribute("id", "root");
  document.body.appendChild(rootEl);

  let childProps;
  let childViewId;
  let childNow;
  let childProducerId;

  const Child: view = ({ _props, _viewId, _now, _producerId }) => {
    childProducerId = _producerId;
    childProps = _props;
    childViewId = _viewId;
    childNow = _now;
    return <div data-testid="bar"></div>;
  };

  const Component: view = ({ foo = observe.foo }) => {
    return (
      <div data-testid="foo">
        <Child foo={foo} />
      </div>
    );
  };

  const app = engine({
    state: defaultState,
    use: [render(<Component />, rootEl)],
  });

  app.start();

  jest.runAllTimers();
  await flushPromises();
  waitFor(() => getByTestId(document.body, "bar")).then((x) => {
    expect(childProps).toBeDefined();
    expect(childViewId).toBeDefined();
    expect(childNow).toBeDefined();
    expect(childProducerId).not.toBeDefined();
    expect(childProps).toEqual({
      foo: "123",
    });
    expect(childNow()).toEqual(expect.any(Number));
    done();
  });
});
Example #19
Source File: root.spec.tsx    From engine with MIT License 5 votes vote down vote up
test("should support various root element formats", async () => {
  const defaultState = {
    foo: "123",
  };

  const addRoot = (id: string) => {
    const rootEl = document.createElement("div");
    rootEl.setAttribute("id", id);
    document.body.appendChild(rootEl);
    return rootEl;
  };

  const component = (id: string) => {
    const Component: view = ({ foo = observe.foo }) => {
      return <div data-testid={id}>{foo}</div>;
    };
    return Component;
  };

  const testComponent = async (id: string) => {
    return waitFor(() => getByTestId(document.body, id)).then((x) => {
      expect(x.innerHTML).toBe("123");
    });
  };

  const ComponentA = component("componentA");
  const ComponentB = component("componentB");
  const ComponentC = component("componentC");
  const ComponentD = component("componentD");
  const ComponentE = component("componentE");
  const ComponentF = component("componentF");
  const ComponentG = component("componentG");

  addRoot("componentD");
  addRoot("componentE");
  addRoot("componentF");
  addRoot("componentG");
  const app = engine({
    state: defaultState,
    use: [
      render(<ComponentA />, addRoot("componentA")),
      render(<ComponentB />, () => addRoot("componentB")),
      render(<ComponentC />, () => Promise.resolve(addRoot("componentC"))),
      render(<ComponentD />, "#componentD"),
      render(<ComponentE />, () => "#componentE"),
      render(<ComponentF />, Promise.resolve("#componentF")),
      render(<ComponentG />, () => Promise.resolve("#componentG")),
    ],
  });

  app.start();

  jest.runAllTimers();
  await flushPromises();
  await testComponent("componentA");
  await testComponent("componentB");
  await testComponent("componentC");
  await testComponent("componentE");
  await testComponent("componentF");
  await testComponent("componentG");
});
Example #20
Source File: propsFalsy.spec.tsx    From engine with MIT License 5 votes vote down vote up
test("Should pass falsy values as well", async (done) => {
  const val = "321";
  const defaultState = {
    foo: true,
  };
  const rootEl = document.createElement("div");
  rootEl.setAttribute("id", "root");
  document.body.appendChild(rootEl);
  const Child: view = ({ foo, toggle = update.foo }) => {
    return (
      <div>
        <div data-testid="foo" data-value={foo}>
          test
        </div>
        <button data-testid="button" onClick={() => toggle.set(!foo)}></button>
      </div>
    );
  };
  const Parent: view = ({ foo = observe.foo }) => {
    return <Child foo={foo} />;
  };

  const app = engine({
    state: defaultState,
    use: [render(<Parent />, rootEl)],
  });

  app.start();

  jest.runAllTimers();
  await flushPromises();
  waitFor(() => getByTestId(document.body, "foo")).then(async (x) => {
    expect(x.dataset.value).toBe("true");
    const button = getByTestId(document.body, "button");
    fireEvent.click(button);
    jest.runAllTimers();
    await flushPromises();
    const newFoo = getByTestId(document.body, "foo");
    expect(newFoo.dataset.value).toBe("false");
    done();
  });
});
Example #21
Source File: props.spec.tsx    From engine with MIT License 5 votes vote down vote up
test("Should propagate changes in props", async (done) => {
  const val = "321";
  const defaultState = {
    foo: "123",
  };
  const rootEl = document.createElement("div");
  rootEl.setAttribute("id", "root");
  document.body.appendChild(rootEl);
  const Child: view = ({ foo = prop.foo, setFoo = update.foo }) => {
    return (
      <div>
        <div data-testid="foo">{foo}</div>;
        <div data-testid="set-foo" onClick={() => setFoo.set(val)}></div>
      </div>
    );
  };
  const Parent: view = ({ foo = observe.foo }) => {
    return <Child foo={foo} />;
  };

  const app = engine({
    state: defaultState,
    use: [render(<Parent />, rootEl)],
  });

  app.start();

  jest.runAllTimers();
  await flushPromises();

  waitFor(() => getByTestId(document.body, "foo")).then(async (x) => {
    expect(x.innerHTML).toBe(defaultState.foo);
    const button = getByTestId(document.body, "set-foo");
    fireEvent.click(button);
    jest.runAllTimers();
    await flushPromises();
    const newFoo = getByTestId(document.body, "foo");
    expect(newFoo.innerHTML).toBe(val);
    done();
  });
});
Example #22
Source File: producers.spec.tsx    From engine with MIT License 5 votes vote down vote up
test("Should mount and unmount producers attached to a component", async (done) => {
  const defaultState = {
    foo: "123",
    shouldMountChild: true,
  };
  const rootEl = document.createElement("div");
  rootEl.setAttribute("id", "root");
  document.body.appendChild(rootEl);
  const Component: view = ({ foo = observe.foo }) => {
    return <div data-testid="foo">{foo}</div>;
  };
  const prodA: producer = ({
    propValue = observe[prop.propName],
    bar = update.bar,
  }) => {
    bar.set(propValue);
  };

  const prodB: producer = ({
    propValue = observe[prop.propName],
    baz = update.baz,
  }) => {
    baz.set(propValue);
  };

  Component.producers([prodA]);
  Component.producers([prodB]);

  const Parent: view = ({ shouldMount = observe.shouldMountChild }) => {
    return <div>{shouldMount && <Component propName="foo"></Component>}</div>;
  };

  let bar;
  let baz;
  const syncValues: producer = ({
    valueBar = observe.bar,
    valueBaz = observe.baz,
  }) => {
    bar = valueBar;
    baz = valueBaz;
  };
  let mountFn;
  const setMount: producer = ({ value = update.shouldMountChild }) => {
    mountFn = value.set;
  };
  let fooFn;
  const setFoo: producer = ({ value = update.foo }) => {
    fooFn = value.set;
  };

  const app = engine({
    state: defaultState,
    use: [
      render(<Parent />, rootEl),
      producers([syncValues, setMount, setFoo]),
    ],
  });

  app.start();

  jest.runAllTimers();
  await flushPromises();

  waitFor(() => getByTestId(document.body, "foo")).then(async (x) => {
    expect(bar).toBe("123");
    expect(baz).toBe("123");
    mountFn(false);
    jest.runAllTimers();
    await flushPromises();
    fooFn("321");
    jest.runAllTimers();
    await flushPromises();
    expect(bar).toBe("123");
    done();
  });
});
Example #23
Source File: path.spec.tsx    From engine with MIT License 5 votes vote down vote up
test("should support path operations with multiple components", async (done) => {
  const defaultState = {
    items: {
      foo: {
        bar: {
          value: "123",
        },
      },
    },
  };
  const rootEl = document.createElement("div");
  rootEl.setAttribute("id", "root");
  document.body.appendChild(rootEl);
  const path1 = path.items.foo.bar;
  const Input: view = ({
    value = get[prop.path].value,
    path2 = update[prop.path].value,
  }) => (
    <input
      data-testid="foo"
      type="text"
      defaultValue={value.value()}
      onChange={(e) => path2.set(e.target.value)}
    />
  );
  const Component: view = ({ path }) => {
    return (
      <div>
        <Input path={path} />
      </div>
    );
  };
  let tempStore;
  const sync: producer = ({ value = observe.items.foo.bar.value }) => {
    tempStore = value;
  };
  const app = engine({
    state: defaultState,
    use: [render(<Component path={path1} />, rootEl), producers([sync])],
  });

  app.start();

  jest.runAllTimers();
  await flushPromises();
  waitFor(() => getByTestId(document.body, "foo")).then((x) => {
    fireEvent.change(x, { target: { value: "321" } });
    jest.runAllTimers();
    expect(tempStore).toBe("321");
    done();
  });
});
Example #24
Source File: events.spec.tsx    From engine with MIT License 5 votes vote down vote up
test("Simple load of a react component", async (done) => {
  const defaultState = {
    foo: "123",
  };
  const rootEl = document.createElement("div");
  rootEl.setAttribute("id", "root");
  document.body.appendChild(rootEl);
  const Component: view = ({ foo = observe.foo }) => {
    return <div data-testid="foo">{foo}</div>;
  };

  expect(Component.displayName).not.toBeUndefined();

  const on = jest.fn();
  const app = engine({
    onEvents: on,
    state: defaultState,
    use: [render(<Component />, rootEl)],
  });

  app.start();

  jest.runAllTimers();
  await flushPromises();
  waitFor(() => getByTestId(document.body, "foo")).then(async (x) => {
    expect(x.innerHTML).toBe(defaultState.foo);
    app.stop();
    jest.runAllTimers();
    await flushPromises();
    expect(extractEvents(on)).toEqual([
      EventNames.ENGINE_STARTED,
      EventNames.MODULE_MOUNTED,
      EventNames.VIEW_MOUNTED,
      EventNames.PRODUCER_MOUNTED,
      EventNames.PRODUCER_CALLED,
      EventNames.PRODUCER_MOUNTED,
      EventNames.PRODUCER_CALLED,
      EventNames.VIEW_UNMOUNTED,
      EventNames.PRODUCER_UNMOUNTED,
      EventNames.PRODUCER_UNMOUNTED,
      EventNames.MODULE_UNMOUNTED,
      EventNames.ENGINE_STOPPED,
    ]);
    done();
  });
});
Example #25
Source File: disableClonning.spec.tsx    From engine with MIT License 5 votes vote down vote up
test("Should not clone children", async (done) => {
  const val = "321";
  const defaultState = {
    baz: "123",
  };
  const rootEl = document.createElement("div");
  rootEl.setAttribute("id", "root");
  document.body.appendChild(rootEl);
  let refs = [];
  const Child: view = ({ foo = prop.children }) => {
    refs.push(foo);
    return <div>{foo}</div>;
  };
  const Parent: view = ({ changeBaz = update.baz, baz = observe.baz }) => {
    return (
      <div>
        <button data-testid="change-baz" onClick={() => changeBaz.set(val)} />
        <Child>
          <div data-testid="foo">123</div>
        </Child>
      </div>
    );
  };

  const app = engine({
    state: defaultState,
    use: [render(<Parent />, rootEl)],
  });

  app.start();

  jest.runAllTimers();
  await flushPromises();
  waitFor(() => getByTestId(document.body, "foo")).then((x) => {
    const button = getByTestId(document.body, "change-baz");
    fireEvent.click(button);
    jest.runAllTimers();
    expect(refs[0]).toBe(refs[refs.length - 1]);
    done();
  });
});
Example #26
Source File: detectChildrenChange.spec.tsx    From engine with MIT License 5 votes vote down vote up
test("should detect children change", async (done) => {
  const val = "321";
  const defaultState = {
    baz: "123",
  };
  const rootEl = document.createElement("div");
  rootEl.setAttribute("id", "root");
  document.body.appendChild(rootEl);
  const Child: view = ({ children }) => {
    // console.log(children);
    return <div>{children}</div>;
  };
  const Parent: view = ({ baz = observe.baz, trigger = update.trigger }) => {
    return (
      <div>
        <Child>
          <div data-testid="foo">{baz}</div>
        </Child>
        <div
          data-testid="change-baz"
          onClick={() => trigger.set(Math.random())}
        >
          trigger
        </div>
      </div>
    );
  };

  const changer: producer = ({
    trigger = observe.trigger,
    updateBaz = update.baz,
  }) => {
    if (!trigger) {
      return;
    }
    updateBaz.set("321");
  };

  const app = engine({
    state: defaultState,
    use: [render(<Parent />, rootEl), producers([changer])],
  });

  app.start();

  jest.runAllTimers();
  await flushPromises();
  waitFor(() => getByTestId(document.body, "foo")).then(async (x) => {
    const button = getByTestId(document.body, "change-baz");
    fireEvent.click(button);
    jest.runAllTimers();
    await flushPromises();
    const value = getNodeText(x);
    expect(value).toBe("321");
    done();
  });
});
Example #27
Source File: viewInstance.spec.tsx    From engine with MIT License 4 votes vote down vote up
test("should create a state instance for a view", async (done) => {
  const defaultState = {
    foo: "123",
  };
  const rootEl = document.createElement("div");
  rootEl.setAttribute("id", "root");
  document.body.appendChild(rootEl);
  let parentViewId;
  let childViewId;
  let childView2Id;

  const Child2: view = ({ _viewId }) => {
    childView2Id = _viewId;
    return <div data-testid="baz">Child view</div>;
  };

  const producerChild2: producer = ({
    updateBaz = update.views[prop._viewId].data.baz,
  }) => {
    updateBaz.set("123");
  };

  Child2.producers([producerChild2]);

  const Child: view = ({ _viewId }) => {
    childViewId = _viewId;
    return (
      <div data-testid="bar">
        Child view
        <div>
          <Child2 foo="bar" />
        </div>
      </div>
    );
  };

  const Component: view = ({
    _viewId,
    updateFoo = update.views[prop._viewId].data.foo,
  }) => {
    parentViewId = _viewId;
    updateFoo.set("bar");
    return (
      <div data-testid="foo">
        <Child />
      </div>
    );
  };

  expect(Component.displayName).not.toBeUndefined();

  let get;
  const monitor: producer = ({ _get = get }) => {
    get = _get;
  };

  const app = engine({
    state: defaultState,
    use: [render(<Component />, rootEl), producers([monitor])],
  });

  app.start();

  jest.runAllTimers();
  await flushPromises();
  waitFor(() => getByTestId(document.body, "baz")).then(async (x) => {
    const parentView = get(path.views[parentViewId]).value();
    const childView = get(path.views[childViewId]).value();
    const childView2 = get(path.views[childView2Id]).value();

    const props = ["createdAt", "data", "rootId", "parentId", "id"];

    expect(Object.keys(parentView)).toEqual(expect.arrayContaining(props));
    expect(Object.keys(childView)).toEqual(expect.arrayContaining(props));
    expect(Object.keys(childView2)).toEqual(expect.arrayContaining(props));
    expect(parentView.data).toStrictEqual({
      foo: "bar",
    });

    expect(childView2.data.baz).toBe("123");
    expect(childView.parentId).toBe(parentView.id);
    expect(childView.rootId).toBe(parentView.id);
    expect(childView2.parentId).toBe(childView.id);
    expect(childView2.rootId).toBe(parentView.id);

    expect(parentView.children[childView.id]).toBeDefined();
    expect(childView.children[childView2.id]).toBeDefined();

    // console.log(parentView, childView, childView2);
    app.stop();

    jest.runAllTimers();
    await flushPromises();

    expect(get(path.views).value()).toEqual({});
    done();
  });
});
Example #28
Source File: UMLEditor.test.tsx    From legend-studio with Apache License 2.0 4 votes vote down vote up
test(
  integrationTest('Class editor without constraints and derived properties'),
  async () => {
    await TEST__openElementFromExplorerTree('ui::TestClass', renderResult);
    const editPanelHeader = renderResult.getByTestId(
      LEGEND_STUDIO_TEST_ID.EDIT_PANEL__HEADER_TABS,
    );
    expect(getByText(editPanelHeader, 'TestClass')).not.toBeNull();
    const classForm = renderResult.getByTestId(
      LEGEND_STUDIO_TEST_ID.CLASS_FORM_EDITOR,
    );
    // Normal properties
    const classProperties = ['a', 'b', 'name', 'person'];
    classProperties.forEach((t) =>
      expect(getByDisplayValue(classForm, t)).not.toBeNull(),
    );
    // Supertype propertes
    const superTypeProperties = [
      'legs',
      'arms',
      'planet',
      'description',
      'founder',
    ];
    superTypeProperties.forEach((superTypeProperty) => {
      // input fields for super type property name are not present/disabled
      expect(queryByDisplayValue(classForm, superTypeProperty)).toBeNull();
      expect(queryByText(classForm, superTypeProperty)).not.toBeNull();
    });
    // Association properties
    const associationProperties = ['testClassSibling'];
    associationProperties.forEach((associationProperty) => {
      // input fields for association property name are not present/disabled
      expect(queryByDisplayValue(classForm, associationProperty)).toBeNull();
      expect(queryByText(classForm, associationProperty)).not.toBeNull();
    });
    // SuperTypes
    fireEvent.click(getByText(classForm, 'Super Types'));
    await waitFor(() => getByText(classForm, 'Animal'));
    // TaggedValues
    fireEvent.click(getByText(classForm, 'Tagged Values'));
    await waitFor(() => getByText(classForm, 'ProfileTest'));
    expect(getByText(classForm, 'tag1')).not.toBeNull();
    expect(getByDisplayValue(classForm, 'test')).not.toBeNull();
    // Stereotypes
    fireEvent.click(getByText(classForm, 'Stereotypes'));
    await waitFor(() => getByText(classForm, 'ProfileTest'));
    expect(getByText(classForm, 'stereotype1')).not.toBeNull();
    // Back to properties. Test more rigorous
    fireEvent.click(getByText(classForm, 'Properties'));
    await waitFor(() => getByText(classForm, 'founder'));
    const inputA = getByDisplayValue(classForm, 'a');
    const propertyA = inputA.parentElement?.parentElement
      ?.parentElement as HTMLElement;
    fireEvent.change(inputA, { target: { value: 'abcdefg' } });
    await waitFor(() => getByDisplayValue(classForm, 'abcdefg'));
    expect(getAllByDisplayValue(propertyA, '1')).toHaveLength(2);
    expect(getByText(propertyA, 'String')).not.toBeNull();
    expect(getAllByRole(propertyA, 'button')).toHaveLength(2);
    fireEvent.click(guaranteeNonNullable(getAllByRole(propertyA, 'button')[1]));
    expect(queryByDisplayValue(classForm, 'abcdefg')).toBeNull();
    // Sub Panel Property
    const inputB = getByDisplayValue(classForm, 'b');
    const propertyB = inputB.parentElement?.parentElement
      ?.parentElement as HTMLElement;
    const buttons = getAllByRole(propertyB, 'button');
    expect(buttons).toHaveLength(2);
    expect(queryByDisplayValue(classForm, 'ProfileTest')).toBeNull();
    const navigateToPropertyButton = guaranteeNonNullable(buttons[0]);
    fireEvent.click(navigateToPropertyButton);
    await waitFor(() => getByText(classForm, 'property'));
    const subPropertyPanel = getByTestId(
      classForm,
      LEGEND_STUDIO_TEST_ID.PANEL,
    );
    expect(
      getByDisplayValue(subPropertyPanel, 'lets write a tag'),
    ).not.toBeNull();
    expect(getAllByText(subPropertyPanel, 'tag2')).not.toBeNull();
    expect(getByText(subPropertyPanel, 'ProfileTest')).not.toBeNull();
    fireEvent.click(getByText(subPropertyPanel, 'Stereotypes'));
    await waitFor(() => getByText(subPropertyPanel, 'stereotype1'));
    fireEvent.click(
      guaranteeNonNullable(getAllByRole(subPropertyPanel, 'button')[0]),
    );
    expect(queryByRole(classForm, 'panel')).toBeNull();
  },
);
Example #29
Source File: viewSelector-multipleHierarchy.spec.tsx    From engine with MIT License 4 votes vote down vote up
test("should support viewSelector() with multiple hierarchy", async (done) => {
  const rootEl = document.createElement("div");
  rootEl.setAttribute("id", "root");
  document.body.appendChild(rootEl);

  /** Child */
  enum ChildIds {
    C = "c",
    D = "d",
  }

  const childSelector = ({ load }) => {
    return load;
  };
  const C: view = () => <div data-testid={ChildIds.C}>{ChildIds.C}</div>;
  const D: view = () => <div data-testid={ChildIds.D}>{ChildIds.D}</div>;

  let _updateChildData;
  const childInit: producer = ({
    startWith,
    updateData = update.views[prop._viewId].data,
  }) => {
    if (!startWith) {
      return;
    }
    _updateChildData = (data) => {
      updateData.set(data);
    };
    updateData.set({
      load: startWith,
    });
  };

  const Child = viewSelector(
    {
      [ChildIds.C]: C,
      [ChildIds.D]: D,
    },
    childSelector,
    [childInit]
  );

  /** Parent */
  enum Ids {
    A = "a",
    B = "b",
  }

  const A: view = () => <div data-testid={Ids.A}>{Ids.A}</div>;
  const B = (props: unknown) => {
    return (
      <div data-testid={Ids.B}>
        <Child startWith={ChildIds.D} />
      </div>
    );
  };

  const selector = ({ loadB, loadA }) => {
    if (!loadB || loadA) {
      return Ids.A;
    } else if (loadB) {
      return Ids.B;
    }
  };

  let _updateParent;
  let _get;
  const init: producer = ({
    get = get,
    updateData = update.views[prop._viewId].data,
  }) => {
    _get = get;
    _updateParent = updateData;
  };

  const Parent = viewSelector(
    {
      [Ids.A]: A,
      [Ids.B]: B,
    },
    selector,
    [init]
  );

  const app = engine({
    use: [render(<Parent />, rootEl)],
  });

  app.start();

  jest.runAllTimers();
  await flushPromises();
  waitFor(() => getByTestId(document.body, Ids.A)).then(async (x) => {
    expect(x.innerHTML).toBe(Ids.A);

    _updateParent.set({
      loadB: true,
    });
    waitFor(() => getByTestId(document.body, Ids.B)).then(async (x) => {
      waitFor(() => getByTestId(document.body, ChildIds.D)).then(async (x) => {
        expect(x.innerHTML).toBe(ChildIds.D);

        _updateChildData({ load: ChildIds.C });

        waitFor(() => getByTestId(document.body, ChildIds.C)).then(
          async (x) => {
            expect(x.innerHTML).toBe(ChildIds.C);
            done();
          }
        );
      });
    });
  });
});