integration/markets-list.test.ts
import "jest-environment-puppeteer";
import Flash from "./helpers/flash";
import { ElementHandle } from "puppeteer";
import { createYesNoMarket } from "./helpers/create-markets";
import { IFlash, IMarket } from "./types/types";
import { waitNextBlock } from "./helpers/wait-new-block";
require("./helpers/beforeAll");
// TODO: Replace uses of `url` with calls to functions in navigation-helper
const url = `${process.env.AUGUR_URL}`;
const CATEGORY_SELECTOR = ".inner-nav-styles_InnerNav__menu-item--visible";
const MARKET_SELECTOR = ".market-common-styles_MarketCommon__container";
const TIMEOUT = 8000;
jest.setTimeout(100000);
let flash: IFlash = new Flash();
const checkNumElements = async (isMarkets: boolean, num: number) => {
const selector = isMarkets ? MARKET_SELECTOR : CATEGORY_SELECTOR;
let elements = await page.$$(selector);
while (elements.length != num) {
elements = await page.$$(selector);
}
return true;
};
const checkMarketNames = async (expectedMarketTitles: string[]) => {
for (let i = 0; i < expectedMarketTitles.length; i++) {
await expect(page).toMatchElement("a", { text: expectedMarketTitles[i] });
}
return;
};
describe("Markets List", () => {
let yesNoMarket: ElementHandle | void;
let yesNoMarketId: string;
const yesNoMarketDesc =
"Will antibiotics be outlawed for agricultural use in China by the end of 2019?";
beforeAll(async () => {
await expect(page).toClick("a[href$='#/markets']");
yesNoMarketId = await page.evaluate(
marketDescription =>
window.integrationHelpers.findMarketId(marketDescription),
yesNoMarketDesc
);
});
afterAll(async () => {
flash.dispose();
});
describe("General View", () => {
it("should paginate in chunks of 10", async () => {
await page.waitForSelector(
".market-common-styles_MarketCommon__container"
);
await checkNumElements(true, 10);
});
it("should display all categories for every loaded market in the sidebar", async () => {
await page.waitForSelector(".inner-nav-styles_InnerNav__menu--main");
await checkNumElements(false, 12);
// TODO: check which categories are present
});
});
describe("Filtering", () => {
beforeEach(async () => {
await page.goto(url + "#/markets?category=politics"); // click sometimes fails because of page rerenders
});
it("should display both submenu bars", async () => {
await page.waitForSelector(".inner-nav-styles_InnerNav__menu--main");
await page.waitForSelector(".inner-nav-styles_InnerNav__menu--submenu");
});
it("should filter market cards", async () => {
// check that header is correct
await expect(page).toMatchElement("h1", { text: "politics" });
// check that number of markets listed is as expected
await checkNumElements(true, 3);
});
it("should populate submenu bar with the tag values for the markets displayed", async () => {
// check that tag submenu has right number of tags displayed
await checkNumElements(false, 17);
});
it("should filter out markets that don't match the selected tags when clicking on tags", async () => {
// when clicking on elections check that only two markets are displayed
await page.goto(url + "#/markets?category=politics&tags=elections"); // click sometimes fails because of page rerenders
await checkNumElements(true, 2);
});
it("should show all markets after clicking the market button", async () => {
await expect(page).toClick("a[href$='#/markets']");
await checkNumElements(true, 10);
});
});
describe("Search", () => {
it("should filter markets to show only ones with searched keyword", async () => {
// enter in a search keyword
await expect(page).toFill(
"input.filter-search-styles_FilterSearch__input",
"jair"
);
await checkNumElements(true, 1);
// check that market that shows up is correct one
await checkMarketNames([
"Will Jair Messias Bolsonaro be elected the president of Brazil in 2018?"
]);
});
it("should not have case sensitive search", async () => {
// make sure clearing search works
await expect(page).toClick(".input-styles_close", { timeout: TIMEOUT });
await expect(page).toFill(
"input.filter-search-styles_FilterSearch__input",
"JAIR"
);
await checkNumElements(true, 1);
});
it("should have markets be searchable by title, tag, or category", async () => {
// search for a category
await expect(page).toClick(".input-styles_close", { timeout: TIMEOUT });
await expect(page).toFill(
"input.filter-search-styles_FilterSearch__input",
"crypto"
);
await checkNumElements(true, 2);
// check that expected titles are present
const expectedMarketTitles = [
"Will Ethereum trade at $2000 or higher at any time before the end of 2018?",
"Millions of Tether tokens issued on "
];
await checkMarketNames(expectedMarketTitles);
await expect(page).toClick(".input-styles_close");
// search for a tag
await expect(page).toFill(
"input.filter-search-styles_FilterSearch__input",
"sfo"
);
await checkNumElements(true, 1);
});
});
describe("Market Cards", () => {
let newMarket: IMarket;
beforeAll(async () => {
await page.goto(url + "#/markets?category=agriculture");
yesNoMarket = await expect(page).toMatchElement("article", {
text: yesNoMarketDesc
});
newMarket = await createYesNoMarket();
await waitNextBlock(10);
});
it("should display market title", async () => {
await expect(yesNoMarket).toMatchElement("a", { text: yesNoMarketDesc });
});
it("should display category and tags in the top left corner of each card", async () => {
await expect(yesNoMarket).toMatchElement("[data-testid='Category-0'", {
text: "AGRICULTURE",
timeout: TIMEOUT
});
await expect(yesNoMarket).toMatchElement("[data-testid='Tags-0'", {
text: "antibiotics"
});
await expect(yesNoMarket).toMatchElement("[data-testid='Tags-1'", {
text: "China"
});
});
it("display the min and max values accurately on either ends of the scale", async () => {
// (0% - 100% for binary markets, min - max for scalar markets)
await expect(yesNoMarket).toMatchElement(
".market-outcomes-yes-no-scalar-styles_MarketOutcomes__min",
{ text: "0 %" }
);
await expect(yesNoMarket).toMatchElement(
".market-outcomes-yes-no-scalar-styles_MarketOutcomes__max",
{ text: "100 %" }
);
});
it("should display stats about volume, settlement Fee, and Expiration Date", async () => {
await expect(yesNoMarket).toMatchElement(".value_volume", { text: "0" });
await expect(yesNoMarket).toMatchElement(".value_fee", { text: "2.00" });
// @todo Figure out how to handle local datetimes
// await expect(yesNoMarket).toMatchElement(".value_expires", { text: "Dec 31, 2019 4:00 PM (UTC -8)"})
});
it("should display a togglable favorites star to the left of the action button on the bottom right of the card", async () => {
await expect(yesNoMarket).toClick(
"button.market-properties-styles_MarketProperties__favorite"
);
await page.waitForSelector(".fa-star");
});
it("should display an action button that reads 'trade' which when clicked brings you to the trade view for that market", async () => {
await expect(page).toClick(
"a.market-properties-styles_MarketProperties__trade"
);
await page.waitForSelector(
".market-header-styles_MarketHeader__back-button",
{ timeout: TIMEOUT }
); // wait to be on right page
const pageUrl = await page.url();
expect(pageUrl).toEqual(
`${process.env.AUGUR_URL}#/market?id=${yesNoMarketId}`
);
});
it("should bring you to the trade view for that market when clicking on market title", async () => {
await expect(page).toClick("span", { text: "back", timeout: TIMEOUT });
await expect(page).toClick("a", {
text: yesNoMarketDesc,
timeout: TIMEOUT
});
await page.waitForSelector(
".market-header-styles_MarketHeader__back-button",
{ timeout: TIMEOUT }
); // wait to be on right page
const pageUrl = await page.url();
expect(pageUrl).toEqual(
`${process.env.AUGUR_URL}#/market?id=${yesNoMarketId}`
);
});
it("should display categorical market outcomes correctly", async () => {
await page.goto(url + "#/markets?category=science&tags=mortality");
const categoricalMarket = await expect(page).toMatchElement("article", {
text:
"What will be the number one killer in the United States by January 1, 2019?",
timeout: TIMEOUT
});
// display the top 3 outcomes for a Categorical Market, with a "+ N More" where N is the number of remaining outcomes
await expect(categoricalMarket).toMatchElement(
".market-outcomes-categorical-styles_MarketOutcomesCategorical__show-more",
{ text: "+ 3 more", timeout: TIMEOUT }
);
const outcomes = await page.$$(
".market-outcomes-categorical-styles_MarketOutcomesCategorical__outcome"
);
expect(outcomes.length).toEqual(6);
// click show more button
await expect(categoricalMarket).toClick(
".market-outcomes-categorical-styles_MarketOutcomesCategorical__show-more"
);
// "+ N More" should change to "- N More" when expanded, should collapse again on click.
await expect(categoricalMarket).toMatchElement(
".market-outcomes-categorical-styles_MarketOutcomesCategorical__show-more",
{ text: "- 3 less", timeout: TIMEOUT }
);
});
it("should display a scale with the current mid-price for the market", async () => {
// go to new markets page
await page.goto(url + "#/markets?category=space");
await page.waitForSelector(
"[data-testid='markets-" + newMarket.id + "']",
{ timeout: TIMEOUT }
);
await expect(page).toMatchElement(
"[data-testid='markets-" + newMarket.id + "'] [data-testid='midpoint']",
{
text: "50.00",
timeout: TIMEOUT
}
);
});
it("should have accurate volume stat", async () => {
// expect volume to start at zero
await page.waitForSelector(
"[data-testid='markets-" + newMarket.id + "']",
{ timeout: TIMEOUT }
);
await expect(page).toMatchElement(
"[data-testid='markets-" + newMarket.id + "'] .value_volume",
{
text: "0",
timeout: TIMEOUT
}
);
// create and fill order
await flash.createMarketOrder(newMarket.id, "1", "sell", ".1", "2");
await waitNextBlock(10);
await flash.fillMarketOrders(newMarket.id, "1", "buy");
await waitNextBlock(10);
// expect volume increase
await page.waitForSelector(
"[data-testid='markets-" + newMarket.id + "']",
{ timeout: TIMEOUT }
);
await expect(page).toMatchElement(
"[data-testid='markets-" + newMarket.id + "'] .value_volume",
{
text: "2.0000",
timeout: TIMEOUT
}
);
});
it("should verify that the midprice moves along the scale appropriately", async () => {
await page.waitForSelector(
"[data-testid='markets-" + newMarket.id + "']",
{ timeout: TIMEOUT }
);
await expect(page).toMatchElement(
"[data-testid='markets-" + newMarket.id + "'] [data-testid='midpoint']",
{
text: "10.00",
timeout: TIMEOUT
}
);
});
});
});