Skip to content
Merged
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
5 changes: 5 additions & 0 deletions TA_dataset/default/commands.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,8 @@
filename = dataset_search_command.py
chunked = true
python.version = python3

[s1query]
filename = dataset_search_command.py
chunked = true
python.version = python3
6 changes: 5 additions & 1 deletion TA_dataset/default/searchbnf.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[dataset-command]
syntax = dataset (account=<string>)? <method>? (search=<string>)? (columns=<string>)? (maxcount=<integer>)? (starttime=<string>)? (endtime=<string>)? (field=<string>)? (function=<string>)? (buckets=<int>)? (createsummaries=<bool>)? (onlyusesummaries=<bool>)?
alias = s1query
shortdesc = Connects to the DataSet API and executes a search.
description = This command connects to the DataSet API and executes a search, and a Splunk event is generated for each result. startTime and endTime are optional alternatives to the Splunk time picker. field only applies to facet; function, buckets, createSummaries and onlyUseSummaries only apply to timeseriesQueries.
comment1 = Search the last 10 minutes for for Action='allow' from any serverHost and return 5,000 results.
Expand All @@ -13,7 +14,10 @@ example4 = | dataset method=facet search="serverHost = *" field=serverHost maxco
usage = public
tags = dataset sentinelone api
maintainer = mike.mcgrail@sentinelone.com
category = generating

# this key no longer exists
# https://docs.splunk.com/Documentation/Splunk/9.1.0/Admin/Searchbnfconf
# category = generating

[method]
syntax=method=(query|powerquery|facet|timeseries)
Expand Down
26 changes: 3 additions & 23 deletions e2e/examples.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { test, expect } from '@playwright/test';
import { goToDataSet } from './utils';
import { goToDataSet, goToExamples, waitForData } from './utils';

test.beforeEach(async ({ page }) => {
await page.goto('/');

await goToDataSet(page);
await goToExamples(page);
});


Expand All @@ -18,28 +19,7 @@ test('Check example page', async ({ page }) => {
// wait for elements to load
await expect(page.getByRole("main").getByText("4. Timeseries Query: This will calculate numeric values over time.")).toHaveCount(1)

// Wait for the "Waiting for data..." text to disappear
console.log("Wait for 'Waiting for data' to disappear")
await page.screenshot({ path: 'playwright-screenshots/page-examples-before-waiting-for-data.png', fullPage: true });
await expect(page.getByText(/Waiting for data/)).toHaveCount(0, {timeout: 15000});

await page.screenshot({ path: 'playwright-screenshots/page-examples-before-checks.png', fullPage: true });

// Check if the page does not contain the text "No results found."
const noResultsCount = await page.getByText(/No results found/).count();
console.log("Page contains 'No results found': ", noResultsCount)
expect(noResultsCount).toBe(0);

// Check if the page does not contain the text "No results found."
const searchFailedCount = await page.getByText(/External search command exited unexpectedly/).count();
console.log("Page contains 'External search command exited unexpectedly': ", searchFailedCount)
expect(searchFailedCount).toBe(0);

const { WAIT_FOR_HUMAN_TO_CHECK_IN_MS: waitForHumanStr} = process.env
const waitForHumanMs = parseInt(waitForHumanStr || '0');
console.log("Waiting for human for: ", waitForHumanMs);

await page.waitForTimeout(waitForHumanMs);
await waitForData(page, "examples");

await page.screenshot({ path: 'playwright-screenshots/page-examples-after-checks.png', fullPage: true });
});
4 changes: 2 additions & 2 deletions e2e/global.setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ setup('login and create account', async ({ page }) => {
// wait for table to appear
await page.getByText(/Account name/).click()

const accountCount = await page.getByRole("main").getByRole("row").getByText(/QaTr/).count();
const accountCount = await page.getByRole("main").getByRole("row").getByText(/E2ET/).count();
console.log("Number of accounts: ", accountCount);
if (accountCount == 0) {
// Open dialog
Expand All @@ -73,7 +73,7 @@ setup('login and create account', async ({ page }) => {
const { DATASET_URL: datasetUrl, DATASET_LOG_ACCESS_READ: datasetReadKey, DATASET_LOG_ACCESS_WRITE: datasetWriteKey } = process.env;

// Fill in values
const accountName = 'QaTr' + (Math.random() * 1e18)
const accountName = 'E2ET' + (Math.random() * 1e18)
console.log("Create account: ", accountName);
await locAccount.fill(accountName);
await locUrl.fill(datasetUrl || '');
Expand Down
38 changes: 38 additions & 0 deletions e2e/search.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { test, expect, Page } from '@playwright/test';
import { goToDataSet, goToSearch } from './utils';

test.beforeEach(async ({ page }) => {
await page.goto('/');

await goToDataSet(page);
await goToSearch(page);
});


test('Simple search - dataset', async ({ page }) => {
await searchFor(page, "| dataset");

await page.screenshot({ path: 'playwright-screenshots/page-search-simple-search-dataset.png', fullPage: true });
});

test('Simple search - s1query', async ({ page }) => {
await searchFor(page, "| s1query");

await page.screenshot({ path: 'playwright-screenshots/page-search-simple-search-s1query.png', fullPage: true });
});

async function searchFor(page: Page, query: string, maxCount: number | undefined = undefined) {
if (maxCount === undefined) {
maxCount = Math.ceil(1000 * Math.random()) % 10 + 5;
}

const finalQuery = `${query} maxcount=${maxCount}`

console.log(`Searching for '${finalQuery}', original was: ${query}`);

await page.getByRole('textbox', { name: 'Search' }).fill(finalQuery);

await page.getByLabel("Search Button").click();

await expect(page.getByText(`Events (${maxCount})`)).toHaveCount(1);
}
40 changes: 40 additions & 0 deletions e2e/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,47 @@
import { Page } from '@playwright/test';
import { test, expect } from '@playwright/test';

export async function goToDataSet(page: Page) {
console.log("Go to DataSet page")
await page.getByLabel('Navigate to Security Data Lake Add-On for Splunk app').click()
await page.screenshot({ path: 'playwright-screenshots/page-home.png', fullPage: true });
}

export async function goToExamples(page: Page) {
console.log("Go to example page");
await page.getByText("DataSet by Example").click();

await expect(page).toHaveTitle(/DataSet by Example /);
}

export async function goToSearch(page: Page) {
console.log("Go to search page");
await page.getByRole('link', { name: 'Search' }).click();

await expect(page).toHaveTitle(/Search /);
}

export async function waitForData(page: Page, key: string) {
// Wait for the "Waiting for data..." text to disappear
console.log("Wait for 'Waiting for data' to disappear")
await page.screenshot({ path: `playwright-screenshots/page-${ key }-before-waiting-for-data.png`, fullPage: true });
await expect(page.getByText(/Waiting for data/)).toHaveCount(0, {timeout: 15000});

await page.screenshot({ path: `playwright-screenshots/page-${ key }-before-checks.png`, fullPage: true });

// Check if the page does not contain the text "No results found."
const noResultsCount = await page.getByText(/No results found/).count();
console.log("Page contains 'No results found': ", noResultsCount)
expect(noResultsCount).toBe(0);

// Check if the page does not contain the text "No results found."
const searchFailedCount = await page.getByText(/External search command exited unexpectedly/).count();
console.log("Page contains 'External search command exited unexpectedly': ", searchFailedCount)
expect(searchFailedCount).toBe(0);

const { WAIT_FOR_HUMAN_TO_CHECK_IN_MS: waitForHumanStr} = process.env
const waitForHumanMs = parseInt(waitForHumanStr || '0');
console.log("Waiting for human for: ", waitForHumanMs);

await page.waitForTimeout(waitForHumanMs);
}