Skip to content

Commit

Permalink
Merge pull request #693 from Altinity/window-functions-tests
Browse files Browse the repository at this point in the history
Window functions tests
  • Loading branch information
Slach authored Dec 23, 2024
2 parents ac28cae + 9f19f33 commit 55f91db
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 10 deletions.
1 change: 1 addition & 0 deletions tests/testflows/regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ def regression(self, before, after):
login.login()

self.context.grafana_version = None
Feature(run=load("testflows.tests.automated.window_functions", "feature"))
Feature(run=load("testflows.tests.automated.sql_editor", "feature"))
Feature(run=load("testflows.tests.automated.data_source_setup", "feature"))
Feature(run=load("testflows.tests.automated.e2e", "feature"))
Expand Down
23 changes: 15 additions & 8 deletions tests/testflows/steps/dashboard/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,25 @@ def click_add_visualization_button(self):
locators.add_visualization.click()


@TestStep(When)
def scroll_to_panel(self, panel_name):
"""Scroll until panel is presented."""

driver = self.context.driver
driver.execute_script("arguments[0].scrollIntoView();", locators.panel(panel_name=panel_name))


@TestStep(When)
def open_dropdown_menu_for_panel(self, panel_name):
"""Open dropdown menu for panel."""

with By(f"waiting panel menu for {panel_name} to be loaded"):
wait_panel_menu_button(panel_name=panel_name)

with And("moving cursor to menu button"):
move_cursor_to_menu_button(panel_name=panel_name)
with By("moving cursor to menu button"):
with delay():
move_cursor_to_menu_button(panel_name=panel_name)

with And("clicking menu button"):
click_menu_button_for_panel(panel_name=panel_name)
with delay():
click_menu_button_for_panel(panel_name=panel_name)


@TestStep(When)
Expand Down Expand Up @@ -151,8 +158,8 @@ def open_panel(self, panel_name):
with When(f"I open dropdown menu for panel {panel_name}"):
open_dropdown_menu_for_panel(panel_name=panel_name)

with When("I open panel view"):
edit_panel(panel_name=panel_name)
with When("I open panel view"):
edit_panel(panel_name=panel_name)


@TestStep(When)
Expand Down
20 changes: 20 additions & 0 deletions tests/testflows/steps/panel/locators.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,26 @@ def query_inspector_refresh_button(self):
driver: WebDriver = current().context.driver
return driver.find_element(SelectBy.CSS_SELECTOR, "[aria-label='Panel inspector Query refresh button']")

@property
def query_inspector_data_tab(self):
driver: WebDriver = current().context.driver
return driver.find_element(SelectBy.CSS_SELECTOR, "[data-testid='data-testid Tab Data']")

@property
def query_inspector_data_options_expand_button(self):
driver: WebDriver = current().context.driver
return driver.find_element(SelectBy.XPATH, "//*[@aria-label='Panel inspector Data content']//button[@aria-label='Expand query row']")

@property
def query_inspector_data_options_dropdown(self):
driver: WebDriver = current().context.driver
return driver.find_element(SelectBy.XPATH, "//*[@aria-label='Panel inspector Data content']//input[@aria-label='Select dataframe']")

@property
def query_inspector_download_csv_button(self):
driver: WebDriver = current().context.driver
return driver.find_element(SelectBy.XPATH, "//*[text()='Download CSV']/../../button")

@property
def query_inspector_url(self):
driver: WebDriver = current().context.driver
Expand Down
41 changes: 41 additions & 0 deletions tests/testflows/steps/panel/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,32 @@ def click_datasource_in_select_datasource_dropdown(self, datasource_name):

locators.select_datasource(datasource_name=datasource_name).click()

@TestStep
def click_data_options_expand_button(self):
"""Click data options expand button."""

locators.query_inspector_data_options_expand_button.click()


@TestStep
def enter_data_options_dropdown(self, row):
"""Enter data options dropdown."""

locators.query_inspector_data_options_dropdown.click()
locators.query_inspector_data_options_dropdown.send_keys(row)
locators.query_inspector_data_options_dropdown.send_keys(Keys.ENTER)

@TestStep
def change_row_for_download(self, row):
"""Change row for download."""

with By("clicking data options expand button"):
with delay():
click_data_options_expand_button()

with By("entering row name into data options dropdown"):
with delay():
enter_data_options_dropdown(row=row)

@TestStep(When)
def click_sql_editor_toggle(self, query_name):
Expand Down Expand Up @@ -278,6 +304,21 @@ def click_query_inspector_close_button(self):

locators.query_inspector_close_button.click()


@TestStep(When)
def click_query_inspector_data_tab(self):
"""Click query inspector data tab."""

locators.query_inspector_data_tab.click()


@TestStep(When)
def click_query_inspector_download_csv_button(self):
"""Click query inspector download csv button."""

locators.query_inspector_download_csv_button.click()


@TestStep(Then)
def check_query_inspector_request(self, url_parts):
"""Check url in query inspector."""
Expand Down
5 changes: 3 additions & 2 deletions tests/testflows/steps/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def create_local_chrome_driver(self, browser, local_webdriver_path, common_optio
"download.directory_upgrade": True,
"profile.default_content_settings.popups": 0,
"download.default_directory": default_download_directory,
"profile.default_content_setting_values.automatic_downloads": 1
},
)
if is_no_sandbox:
Expand Down Expand Up @@ -119,7 +120,7 @@ def webdriver(
local_webdriver_path=None,
is_no_sandbox=False,
is_headless=False,
incognito=True,
incognito=False,
global_wait_time=1,
clean_up=True,
suite="grafana"
Expand Down Expand Up @@ -174,7 +175,7 @@ def webdriver(


@TestStep(Given)
def create_driver(self, incognito=True, clean_up=True, suite=None):
def create_driver(self, incognito=False, clean_up=True, suite=None):
"""Create a driver based on the arguments in the context."""

driver = webdriver(
Expand Down
160 changes: 160 additions & 0 deletions tests/testflows/tests/automated/window_functions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
from numpy import corrcoef
from testflows.core import *
from steps.delay import delay
from testflows.asserts import error

import csv
import steps.ui as ui
import steps.actions as actions
import steps.panel.view as panel
import steps.dashboard.view as dashboard
import steps.dashboards.view as dashboards
import steps.panel.sql_editor.view as sql_editor

from requirements.requirements import *


@TestOutline
def window_functions_outline(self, panel_name, panel_names, column=None):
"""Check that grafana plugin supports window functions."""

with When(f"I download data for {panel_name} panel{'' if column is None else ', ' + column + ' column'}"):
with When("I scroll down to the panel"):
if panel_names.index(panel_name) != 0:
dashboard.scroll_to_panel(panel_name=panel_names[panel_names.index(panel_name) - 1])

with When(f"I open panel {panel_name}"):
with delay():
dashboard.open_panel(panel_name=panel_name)

with And("I open Query inspector"):
with delay(after=0.5):
panel.click_inspect_query_button()

with And("I open Data tab in query inspector modal"):
with delay(after=0.5):
panel.click_query_inspector_data_tab()

if not (column is None):
with And("I change csv file to download"):
with delay():
panel.change_row_for_download(row="Series joined by time")

with And("I download csv data file"):
with delay():
panel.click_query_inspector_download_csv_button()

with And("I close query inspector"):
with delay():
panel.click_query_inspector_close_button()

with And("I click discard changes"):
with delay():
panel.click_discard_button()

with When(f"I download data for {panel_name} - without window functions panel{'' if column is None else ', ' + column + ' column'}"):
with When(f"I open panel {panel_name} - without window functions"):
with delay():
dashboard.open_panel(panel_name=f"{panel_name} - without window functions")

with And("I open Query inspector"):
with delay(after=0.5):
panel.click_inspect_query_button()

with And("I open Data tab in query inspector modal"):
with delay(after=0.5):
panel.click_query_inspector_data_tab()

if not (column is None):
with And("I change csv file to download"):
with delay():
panel.change_row_for_download(row="Series joined by time")

with And("I download csv data file"):
with delay():
panel.click_query_inspector_download_csv_button()

with And("I close query inspector"):
with delay():
panel.click_query_inspector_close_button()

with And("I click discard changes"):
with delay():
panel.click_discard_button()

with Then("I save two csv files"):
with delay():
with By("saving container id"):
r = self.context.cluster.command(None, "docker ps -a | grep '4444/tcp, 5900/tcp'")
container_id = r.output.split(" ")[0]
column_name = '' if column is None else '/column' + column[4]

with By("moving csv file from docker"):
r = self.context.cluster.command(None, f"rm -rf tests/automated/window_functions/{panel_name[1:]}{column_name}")
r = self.context.cluster.command(None, f"mkdir -p tests/automated/window_functions/{panel_name[1:]}{column_name}")
r = self.context.cluster.command(None, f"docker cp {container_id}:/home/seluser/Downloads/ tests/automated/window_functions/{panel_name[1:]}{column_name}")
r = self.context.cluster.command(None, f"docker exec {container_id} rm -rf /home/seluser/Downloads/")

with Then("I compare two csv files"):
with delay():
with By("defining filenames"):
filename_with_window_functions = self.context.cluster.command(None, f"ls tests/automated/window_functions/{panel_name[1:]}{column_name}/Downloads/*{panel_name[1:]}-*").output[1:-1]
filename_without_window_functions = self.context.cluster.command(None, f"ls tests/automated/window_functions/{panel_name[1:]}{column_name}/Downloads/*{panel_name[1:]}\ *").output[1:-1]

with By("getting values from files"):
with Step("without window functions"):
file_without_window_functions = open(filename_without_window_functions)
data_without_window_functions = []
for row in csv.reader(file_without_window_functions):
data_without_window_functions.append(row[1])
file_without_window_functions.close()

with Step("with window functions"):
file_with_window_functions = open(filename_with_window_functions)
data_with_window_functions = []
for row in csv.reader(file_with_window_functions):
data_with_window_functions.append(row[1])
file_with_window_functions.close()

with By("calculating correlation between this values"):
data_without_window_functions = [0 if i == '' else float(i) for i in data_without_window_functions[1:]]
data_with_window_functions = [0 if i == '' else float(i) for i in data_with_window_functions[1:]]
correlation = corrcoef(data_without_window_functions[1:], data_with_window_functions[1:])[0,1]
note(f"correlation for {panel_name}: {correlation}")
note(data_without_window_functions)
note(data_with_window_functions)
assert correlation > 0.99, error()

@TestFeature
@Name("window functions")
def feature(self):
"""Check that grafana plugin supports window functions."""

panel_names = [
'$delta',
'$deltaColumns',
'$deltaColumnsAggregated',
'$increase',
'$increaseColumns',
'$increaseColumnsAggregated',
'$perSecond',
'$perSecondColumns',
'$perSecondColumnsAggregated',
'$rate',
'$rateColumns',
'$rateColumnsAggregated',
]

with Given(f"I open dashboard window functions"):
ui.open_endpoint(endpoint='http://grafana:3000/d/de6482iletr0gc/window-functions')

for panel_name in panel_names:
if "Columns" in panel_name:
with Scenario(f"{panel_name} function first row"):
window_functions_outline(panel_name=panel_name, panel_names=panel_names, column="test1 (0)")

with Scenario(f"{panel_name} function second row"):
window_functions_outline(panel_name=panel_name, panel_names=panel_names, column="test2 (1)")
else:
with Scenario(f"{panel_name} function"):
window_functions_outline(panel_name=panel_name, panel_names=panel_names)

0 comments on commit 55f91db

Please sign in to comment.