|
|
import { expect, Page, test } from "@playwright/test"; |
|
|
import uaParser from "ua-parser-js"; |
|
|
|
|
|
|
|
|
test( |
|
|
"user should be able to use slider input", |
|
|
{ |
|
|
tag: ["@release", "@workspace"], |
|
|
}, |
|
|
async ({ page }) => { |
|
|
await page.goto("/"); |
|
|
await page.waitForSelector('[data-testid="mainpage_title"]', { |
|
|
timeout: 30000, |
|
|
}); |
|
|
|
|
|
await page.waitForSelector('[id="new-project-btn"]', { |
|
|
timeout: 30000, |
|
|
}); |
|
|
|
|
|
let modalCount = 0; |
|
|
try { |
|
|
const modalTitleElement = await page?.getByTestId("modal-title"); |
|
|
if (modalTitleElement) { |
|
|
modalCount = await modalTitleElement.count(); |
|
|
} |
|
|
} catch (error) { |
|
|
modalCount = 0; |
|
|
} |
|
|
|
|
|
while (modalCount === 0) { |
|
|
await page.getByText("New Flow", { exact: true }).click(); |
|
|
await page.waitForSelector('[data-testid="modal-title"]', { |
|
|
timeout: 3000, |
|
|
}); |
|
|
modalCount = await page.getByTestId("modal-title")?.count(); |
|
|
} |
|
|
|
|
|
const getUA = await page.evaluate(() => navigator.userAgent); |
|
|
const userAgentInfo = uaParser(getUA); |
|
|
|
|
|
await page.waitForSelector('[data-testid="blank-flow"]', { |
|
|
timeout: 30000, |
|
|
}); |
|
|
await page.getByTestId("blank-flow").click(); |
|
|
await page.getByTestId("sidebar-search-input").click(); |
|
|
await page.getByTestId("sidebar-search-input").fill("ollama"); |
|
|
|
|
|
await page.waitForSelector('[data-testid="modelsOllama"]', { |
|
|
timeout: 3000, |
|
|
}); |
|
|
|
|
|
await page |
|
|
.getByTestId("modelsOllama") |
|
|
.dragTo(page.locator('//*[@id="react-flow-id"]')); |
|
|
await page.mouse.up(); |
|
|
await page.mouse.down(); |
|
|
await page.getByTestId("fit_view").click(); |
|
|
await page.getByTestId("zoom_out").click(); |
|
|
await page.getByTestId("zoom_out").click(); |
|
|
|
|
|
await page.getByTestId("title-Ollama").click(); |
|
|
await page.getByTestId("code-button-modal").click(); |
|
|
|
|
|
let cleanCode = await extractAndCleanCode(page); |
|
|
|
|
|
|
|
|
cleanCode = cleanCode.replace("FloatInput(", "SliderInput("); |
|
|
cleanCode = cleanCode.replace( |
|
|
"from langflow.io import BoolInput, DictInput, DropdownInput, FloatInput, IntInput, StrInput", |
|
|
"from langflow.io import BoolInput, DictInput, DropdownInput, FloatInput, IntInput, StrInput, SliderInput", |
|
|
); |
|
|
|
|
|
cleanCode = cleanCode.replace( |
|
|
"value=0.2,", |
|
|
"value=0.2, range_spec=RangeSpec(min=3, max=30, step=1), min_label='test', max_label='test2', min_label_icon='pencil-ruler', max_label_icon='palette', slider_buttons=False, slider_buttons_options=[], slider_input=False,", |
|
|
); |
|
|
|
|
|
await page.locator("textarea").last().press(`ControlOrMeta+a`); |
|
|
await page.keyboard.press("Backspace"); |
|
|
await page.locator("textarea").last().fill(cleanCode); |
|
|
await page.locator('//*[@id="checkAndSaveBtn"]').click(); |
|
|
|
|
|
await page.getByTestId("fit_view").click(); |
|
|
|
|
|
await mutualValidation(page); |
|
|
|
|
|
await moveSlider(page, "right", false); |
|
|
|
|
|
|
|
|
|
|
|
await page.waitForTimeout(500); |
|
|
|
|
|
await page.getByTestId("zoom_out").click(); |
|
|
|
|
|
await page.getByTestId("more-options-modal").click(); |
|
|
await page.getByText("Controls", { exact: true }).last().click(); |
|
|
await expect( |
|
|
page.getByTestId("default_slider_display_value_advanced"), |
|
|
).toHaveText("19.00"); |
|
|
|
|
|
await moveSlider(page, "left", true); |
|
|
|
|
|
await page.waitForTimeout(500); |
|
|
|
|
|
await expect( |
|
|
page.getByTestId("default_slider_display_value_advanced"), |
|
|
).toHaveText("14.00"); |
|
|
|
|
|
await page.getByText("Close").last().click(); |
|
|
|
|
|
await expect(page.getByTestId("default_slider_display_value")).toHaveText( |
|
|
"14.00", |
|
|
); |
|
|
}, |
|
|
); |
|
|
|
|
|
async function extractAndCleanCode(page: Page): Promise<string> { |
|
|
const outerHTML = await page |
|
|
.locator('//*[@id="codeValue"]') |
|
|
.evaluate((el) => el.outerHTML); |
|
|
|
|
|
const valueMatch = outerHTML.match(/value="([\s\S]*?)"/); |
|
|
if (!valueMatch) { |
|
|
throw new Error("Could not find value attribute in the HTML"); |
|
|
} |
|
|
|
|
|
let codeContent = valueMatch[1] |
|
|
.replace(/"/g, '"') |
|
|
.replace(/&/g, "&") |
|
|
.replace(/</g, "<") |
|
|
.replace(/>/g, ">") |
|
|
.replace(/'/g, "'") |
|
|
.replace(///g, "/"); |
|
|
|
|
|
return codeContent; |
|
|
} |
|
|
|
|
|
async function mutualValidation(page: Page) { |
|
|
await expect(page.getByTestId("default_slider_display_value")).toHaveText( |
|
|
"3.00", |
|
|
); |
|
|
await expect(page.getByTestId("min_label")).toHaveText("test"); |
|
|
await expect(page.getByTestId("max_label")).toHaveText("test2"); |
|
|
await expect(page.getByTestId("icon-pencil-ruler")).toBeVisible(); |
|
|
await expect(page.getByTestId("icon-palette")).toBeVisible(); |
|
|
} |
|
|
async function moveSlider( |
|
|
page: Page, |
|
|
side: "left" | "right", |
|
|
advanced: boolean = false, |
|
|
) { |
|
|
const thumbSelector = `slider_thumb${advanced ? "_advanced" : ""}`; |
|
|
const trackSelector = `slider_track${advanced ? "_advanced" : ""}`; |
|
|
|
|
|
await page.getByTestId(thumbSelector).click(); |
|
|
|
|
|
const trackBoundingBox = await page.getByTestId(trackSelector).boundingBox(); |
|
|
|
|
|
if (trackBoundingBox) { |
|
|
const moveDistance = |
|
|
trackBoundingBox.width * 0.1 * (side === "left" ? -1 : 1); |
|
|
const centerX = trackBoundingBox.x + trackBoundingBox.width / 2; |
|
|
const centerY = trackBoundingBox.y + trackBoundingBox.height / 2; |
|
|
|
|
|
await page.mouse.move(centerX + moveDistance, centerY); |
|
|
await page.mouse.down(); |
|
|
await page.mouse.up(); |
|
|
} |
|
|
} |
|
|
|