Skip to content

Support secondary omni search results #63

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,118 changes: 2,118 additions & 0 deletions api-stubs/definition-search-map.json

Large diffs are not rendered by default.

704 changes: 704 additions & 0 deletions api-stubs/definition-search-test.json

Large diffs are not rendered by default.

337 changes: 262 additions & 75 deletions src/UnisonShare/OmniSearch.elm

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions src/css/unison-share/omni-search.css
Original file line number Diff line number Diff line change
Expand Up @@ -262,13 +262,17 @@
}
}

.main-result-sheet.empty-state {
color: var(--u-color_text_very-subdued);
.main-result-sheet .empty-state {
color: var(--u-color_text_subdued);
font-weight: bold;
text-align: center;
font-size: var(--font-size-base);
padding: 2rem;
}

.main-result-sheet .empty-state_small {
color: var(--u-color_text_subdued);
}
}

.omni-search:focus-within {
Expand Down
263 changes: 263 additions & 0 deletions tests/e2e/OmniSearch.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
import { test, Page, expect } from "@playwright/test";
import * as API from "./TestHelpers/Api";

test.beforeEach(async ({ page }) => {
await API.getAccount(page, "@testuser");
await API.getCatalog(page);
await API.getWebsiteFeed(page);
});

test("can see the search field", async ({ page }) => {
const response = await page.goto("http://localhost:1234/");
expect(response?.status()).toBeLessThan(400);

await expect(searchField(page)).toBeVisible();
});

test.describe("definition search", () => {
test.describe('query: "base" with definition matches and entity matches', () => {
const query = "base";

test.beforeEach(async ({ page }) => {
await page.goto("http://localhost:1234/");
await API.getDefinitionSearch(page, query);
await API.getEntitySearch(page, `@${query}`);

const field = searchField(page);
await field.focus();
await field.fill(query);
});

test("shows definitions matches", async ({ page }) => {
await expect(searchResults(page)).toBeVisible();
await expect(definitionMatches(page)).toHaveCount(3);
});

test("shows entity matches", async ({ page }) => {
await expect(searchResults(page)).toBeVisible();
await expect(projectMatches(page)).toHaveCount(2);
await expect(userMatches(page)).toHaveCount(1);
});
});

test.describe('query: "map" with only has definition matches', () => {
const query = "map";

test.beforeEach(async ({ page }) => {
await page.goto("http://localhost:1234/");
await API.getDefinitionSearch(page, query);
await API.getEntitySearch(page, `@${query}`, []);

const field = searchField(page);
await field.focus();
await field.fill(query);
});

test("shows definitions matches", async ({ page }) => {
await expect(searchResults(page)).toBeVisible();
await expect(definitionMatches(page)).toHaveCount(3);
});

test("doesn't show any entity matches", async ({ page }) => {
await expect(searchResults(page)).toBeVisible();
await expect(projectMatches(page)).toHaveCount(0);
await expect(userMatches(page)).toHaveCount(0);
});
});

test.describe('query: "base" with only entity matches', () => {
const query = "base";

test.beforeEach(async ({ page }) => {
await page.goto("http://localhost:1234/");
await API.getDefinitionSearch(page, query, []);
await API.getEntitySearch(page, `@${query}`);
});

test("shows the entity matches", async ({ page }) => {
const field = searchField(page);
await field.focus();
await field.fill(query);

await expect(searchResults(page)).toBeVisible();
await expect(projectMatches(page)).toHaveCount(2);
await expect(userMatches(page)).toHaveCount(1);
});

test("shows definition search empty state", async ({ page }) => {
const field = searchField(page);
await field.focus();
await field.fill(query);

await expect(searchResults(page)).toBeVisible();
await expect(definitionMatches(page)).toHaveCount(0);
await expect(page.getByText("No definitions matched")).toBeVisible();
});
});

test.describe('query: "map" with no matches', () => {
const query = "map";

test.beforeEach(async ({ page }) => {
await page.goto("http://localhost:1234/");
await API.getDefinitionSearch(page, query, []);
await API.getEntitySearch(page, `@${query}`, []);
});

test("doesn't show any matches", async ({ page }) => {
const field = searchField(page);
await field.focus();
await field.fill(query);

await expect(searchResults(page)).toBeVisible();
await expect(projectMatches(page)).toHaveCount(0);
await expect(userMatches(page)).toHaveCount(0);
await expect(definitionMatches(page)).toHaveCount(0);
});

test("shows an empty state", async ({ page }) => {
const field = searchField(page);
await field.focus();
await field.fill(query);

await expect(searchResults(page)).toBeVisible();
await expect(page.getByText("No matches found")).toBeVisible();
});
});
});

test.describe("entity search", () => {
test.describe('query "@unison" that has user and project matches, but no definition matches', () => {
test.beforeEach(async ({ page }) => {
await page.goto("http://localhost:1234/");
await API.getDefinitionSearch(page, "unison", []);
await API.getEntitySearch(page, "@unison");
});

test("shows entity matches", async ({ page }) => {
const field = searchField(page);
await field.focus();
await field.fill("@unison");

await expect(searchResults(page)).toBeVisible();
await expect(projectMatches(page)).toHaveCount(2);
await expect(userMatches(page)).toHaveCount(1);
});

test("doesn't show any definition matches", async ({ page }) => {
const field = searchField(page);
await field.focus();
await field.fill("@unison");

await expect(searchResults(page)).toBeVisible();
await expect(definitionMatches(page)).toHaveCount(0);
});
});

test.describe('query "@base" that has project matches and definition matches', () => {
test.beforeEach(async ({ page }) => {
await page.goto("http://localhost:1234/");
await API.getDefinitionSearch(page, "base");
await API.getEntitySearch(page, "@base");

const field = searchField(page);
await field.focus();
await field.fill("@base");
});

test("shows entity matches", async ({ page }) => {
await expect(searchResults(page)).toBeVisible();
await expect(projectMatches(page)).toHaveCount(2);
await expect(userMatches(page)).toHaveCount(1);
});

test("shows definition matches", async ({ page }) => {
await expect(searchResults(page)).toBeVisible();
await expect(definitionMatches(page)).toHaveCount(3);
});
});

test.describe('query "@base" with only definition matches', () => {
const query = "@base";

test.beforeEach(async ({ page }) => {
await page.goto("http://localhost:1234/");
await API.getDefinitionSearch(page, query.replace("@", ""));
await API.getEntitySearch(page, query, []);
});

test("shows definition matches", async ({ page }) => {
const field = searchField(page);
await field.focus();
await field.fill(query);

await expect(searchResults(page)).toBeVisible();
await expect(definitionMatches(page)).toHaveCount(3);
});

test("shows entity search empty state", async ({ page }) => {
const field = searchField(page);
await field.focus();
await field.fill(query);

await expect(searchResults(page)).toBeVisible();
await expect(projectMatches(page)).toHaveCount(0);
await expect(userMatches(page)).toHaveCount(0);
await expect(
page.getByText("No users or projects matched"),
).toBeVisible();
});
});

test.describe('query "@nomatches" with no matches', () => {
const query = "@nomatches";

test.beforeEach(async ({ page }) => {
await page.goto("http://localhost:1234/");
await API.getDefinitionSearch(page, query.replace("@", ""), []);
await API.getEntitySearch(page, query, []);
});

test("doesn't show any matches", async ({ page }) => {
const field = searchField(page);
await field.focus();
await field.fill(query);

await expect(searchResults(page)).toBeVisible();
await expect(projectMatches(page)).toHaveCount(0);
await expect(userMatches(page)).toHaveCount(0);
await expect(definitionMatches(page)).toHaveCount(0);
});

test("shows an empty state", async ({ page }) => {
const field = searchField(page);
await field.focus();
await field.fill(query);

await expect(searchResults(page)).toBeVisible();
await expect(page.getByText("No matches found")).toBeVisible();
});
});
});

// Helpers

function searchField(page: Page) {
return page.locator("search").getByRole("textbox");
}

function searchResults(page: Page) {
return page.locator(".main-result-sheet");
}

function definitionMatches(page: Page) {
return page.locator(".definition-match");
}

function projectMatches(page: Page) {
return page.locator(".project-match");
}

function userMatches(page: Page) {
return page.locator(".user-match");
}
33 changes: 33 additions & 0 deletions tests/e2e/TestHelpers/Api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { Page } from "@playwright/test";
import {
project,
contributionTimeline,
definitionSearchMatch,
projectSearchMatch,
userSearchMatch,
userDetails,
org,
contribution,
Expand Down Expand Up @@ -280,6 +283,34 @@ async function getProjectContributionMergeCheck_(
});
}

// -- SEARCH

async function getDefinitionSearch(page: Page, query = "map", results = null) {
return get(page, {
url: `/search-definitions?query=${query}`,
status: 200,
data: {
results: results || [
definitionSearchMatch(),
definitionSearchMatch(),
definitionSearchMatch(),
],
},
});
}

async function getEntitySearch(page: Page, query = "@base", results = null) {
return get(page, {
url: `/search?query=%40${query.replace("@", "")}`,
status: 200,
data: results || [
projectSearchMatch(),
userSearchMatch(),
projectSearchMatch(),
],
});
}

// -- UTIL

type Response = {
Expand Down Expand Up @@ -318,5 +349,7 @@ export {
getProjectContributionTimeline_,
getProjectContributionMergeCheck,
getProjectContributionMergeCheck_,
getDefinitionSearch,
getEntitySearch,
get,
};
Loading