enhance services page + udpate script and tests

* add timeout to execute nomatch showing in order to execute it after the filter logic
* add services card filter : now can filter with name, method or draft/online state
* display no matching filter on services card and service settings too
* card services filtering only showing if at least 4 services
*add new services filter to testing
*update test utils to try fixing issue
This commit is contained in:
Jordan Blasenhauer 2024-02-26 12:20:39 +01:00
parent d1f2455f96
commit af667ada49
7 changed files with 634 additions and 37 deletions

File diff suppressed because one or more lines are too long

View file

@ -38,30 +38,30 @@ const setFilterGlobal = new FilterSettings(
document
.querySelector("input#settings-filter")
.addEventListener("input", () => {
console.log("input");
const tabs = document
.querySelector("[data-global-config-tabs-desktop]")
.querySelectorAll("[data-tab-handler]");
let isAllHidden = true;
for (let i = 0; i < tabs.length; i++) {
const plugin = tabs[i];
if (!plugin.classList.contains("hidden")) {
console.log(plugin);
isAllHidden = false;
break;
setTimeout(() => {
const tabs = document
.querySelector("[data-global-config-tabs-desktop]")
.querySelectorAll("[data-tab-handler]");
let isAllHidden = true;
for (let i = 0; i < tabs.length; i++) {
const plugin = tabs[i];
if (!plugin.classList.contains("hidden")) {
isAllHidden = false;
break;
}
}
}
const formEl = document.querySelector("[data-global-config-form]");
const noMatchEl = document.querySelector("[data-global-config-nomatch]");
const formEl = document.querySelector("[data-global-config-form]");
const noMatchEl = document.querySelector("[data-global-config-nomatch]");
if (isAllHidden) {
noMatchEl.classList.remove("hidden");
formEl.classList.add("hidden");
}
if (isAllHidden) {
noMatchEl.classList.remove("hidden");
formEl.classList.add("hidden");
}
if (!isAllHidden) {
formEl.classList.remove("hidden");
noMatchEl.classList.add("hidden");
}
if (!isAllHidden) {
formEl.classList.remove("hidden");
noMatchEl.classList.add("hidden");
}
}, 20);
});

View file

@ -1044,6 +1044,308 @@ class Multiple {
}
}
class Dropdown {
constructor(prefix = "services") {
this.prefix = prefix;
this.container = document.querySelector("main");
this.lastDrop = "";
this.initDropdown();
}
initDropdown() {
this.container.addEventListener("click", (e) => {
//SELECT BTN LOGIC
try {
if (
e.target
.closest("button")
.hasAttribute(`data-${this.prefix}-setting-select`) &&
!e.target.closest("button").hasAttribute(`disabled`)
) {
const btnName = e.target
.closest("button")
.getAttribute(`data-${this.prefix}-setting-select`);
if (this.lastDrop !== btnName) {
this.lastDrop = btnName;
this.closeAllDrop();
}
this.toggleSelectBtn(e);
}
} catch (err) {}
//SELECT DROPDOWN BTN LOGIC
try {
if (
e.target
.closest("button")
.hasAttribute(`data-${this.prefix}-setting-select-dropdown-btn`)
) {
const btn = e.target.closest("button");
const btnValue = btn.getAttribute("value");
const btnSetting = btn.getAttribute(
`data-${this.prefix}-setting-select-dropdown-btn`,
);
//stop if same value to avoid new fetching
const isSameVal = this.isSameValue(btnSetting, btnValue);
if (isSameVal) return this.hideDropdown(btnSetting);
//else, add new value to custom
this.setSelectNewValue(btnSetting, btnValue);
//close dropdown and change style
this.hideDropdown(btnSetting);
if (
!e.target.closest("button").hasAttribute(`data-${this.prefix}-file`)
) {
this.changeDropBtnStyle(btnSetting, btn);
}
//show / hide filter
if (btnSetting === "instances") {
this.hideFilterOnLocal(btn.getAttribute("data-_type"));
}
}
} catch (err) {}
});
}
closeAllDrop() {
const drops = document.querySelectorAll(
`[data-${this.prefix}-setting-select-dropdown]`,
);
drops.forEach((drop) => {
drop.classList.add("hidden");
drop.classList.remove("flex");
document
.querySelector(
`svg[data-${this.prefix}-setting-select="${drop.getAttribute(
`data-${this.prefix}-setting-select-dropdown`,
)}"]`,
)
.classList.remove("rotate-180");
});
}
isSameValue(btnSetting, value) {
const selectCustom = document.querySelector(
`[data-${this.prefix}-setting-select-text="${btnSetting}"]`,
);
const currVal = selectCustom.textContent;
return currVal === value ? true : false;
}
setSelectNewValue(btnSetting, value) {
const selectCustom = document.querySelector(
`[data-${this.prefix}-setting-select="${btnSetting}"]`,
);
selectCustom.querySelector(
`[data-${this.prefix}-setting-select-text]`,
).textContent = value;
}
hideDropdown(btnSetting) {
//hide dropdown
const dropdownEl = document.querySelector(
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`,
);
dropdownEl.classList.add("hidden");
dropdownEl.classList.remove("flex");
//svg effect
const dropdownChevron = document.querySelector(
`svg[data-${this.prefix}-setting-select="${btnSetting}"]`,
);
dropdownChevron.classList.remove("rotate-180");
}
changeDropBtnStyle(btnSetting, selectedBtn) {
const dropdownEl = document.querySelector(
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`,
);
//reset dropdown btns
const btnEls = dropdownEl.querySelectorAll("button");
btnEls.forEach((btn) => {
btn.classList.remove(
"bg-primary",
"dark:bg-primary",
"text-gray-300",
"text-gray-300",
);
btn.classList.add("bg-white", "dark:bg-slate-700", "text-gray-700");
});
//highlight clicked btn
selectedBtn.classList.remove(
"bg-white",
"dark:bg-slate-700",
"text-gray-700",
);
selectedBtn.classList.add("dark:bg-primary", "bg-primary", "text-gray-300");
}
toggleSelectBtn(e) {
const attribute = e.target
.closest("button")
.getAttribute(`data-${this.prefix}-setting-select`);
//toggle dropdown
const dropdownEl = document.querySelector(
`[data-${this.prefix}-setting-select-dropdown="${attribute}"]`,
);
const dropdownChevron = document.querySelector(
`svg[data-${this.prefix}-setting-select="${attribute}"]`,
);
dropdownEl.classList.toggle("hidden");
dropdownEl.classList.toggle("flex");
dropdownChevron.classList.toggle("rotate-180");
}
//hide date filter on local
hideFilterOnLocal(type) {
if (type === "local") {
this.hideInp(`input#from-date`);
this.hideInp(`input#to-date`);
}
if (type !== "local") {
this.showInp(`input#from-date`);
this.showInp(`input#to-date`);
}
}
showInp(selector) {
document.querySelector(selector).closest("div").classList.add("flex");
document.querySelector(selector).closest("div").classList.remove("hidden");
}
hideInp(selector) {
document.querySelector(selector).closest("div").classList.add("hidden");
document.querySelector(selector).closest("div").classList.remove("flex");
}
}
class Filter {
constructor(prefix = "services") {
this.prefix = prefix;
this.container =
document.querySelector(`[data-${this.prefix}-filter]`) || null;
this.keyInp = document.querySelector("input#service-name-keyword");
this.stateValue = "all";
this.methodValue = "all";
this.initHandler();
}
initHandler() {
if (!this.container) return;
//STATE HANDLER
this.container.addEventListener("click", (e) => {
try {
if (
e.target
.closest("button")
.getAttribute(`data-${this.prefix}-setting-select-dropdown-btn`) ===
"state"
) {
setTimeout(() => {
const value = document
.querySelector(
`[data-${this.prefix}-setting-select-text="state"]`,
)
.textContent.trim()
.toLowerCase();
this.stateValue = value;
//run filter
this.filter();
}, 10);
}
} catch (err) {}
});
//METHOD HANDLER
this.container.addEventListener("click", (e) => {
try {
if (
e.target
.closest("button")
.getAttribute(`data-${this.prefix}-setting-select-dropdown-btn`) ===
"method"
) {
setTimeout(() => {
const value = document
.querySelector(
`[data-${this.prefix}-setting-select-text="method"]`,
)
.textContent.trim()
.toLowerCase();
this.methodValue = value;
//run filter
this.filter();
}, 10);
}
} catch (err) {}
});
//KEYWORD HANDLER
this.keyInp.addEventListener("input", (e) => {
this.filter();
});
}
filter() {
const services = document.querySelectorAll(`[data-${this.prefix}-card]`);
if (services.length === 0) return;
//reset
for (let i = 0; i < services.length; i++) {
const el = services[i];
el.classList.remove("hidden");
}
//filter type
this.setFilterState(services);
this.setFilterMethod(services);
this.setFilterKeyword(services);
}
setFilterState(services) {
if (this.stateValue === "all") return;
for (let i = 0; i < services.length; i++) {
const el = services[i];
console.log(el);
const type = el
.querySelector(`[data-${this.prefix}-state]`)
.getAttribute(`data-${this.prefix}-state`)
.trim()
.toLowerCase();
if (type !== this.stateValue) el.classList.add("hidden");
}
}
setFilterMethod(services) {
if (this.methodValue === "all") return;
for (let i = 0; i < services.length; i++) {
const el = services[i];
const type = el
.querySelector(`[data-${this.prefix}-method]`)
.getAttribute(`data-${this.prefix}-method`)
.trim()
.toLowerCase();
if (type !== this.methodValue) el.classList.add("hidden");
}
}
setFilterKeyword(jobs) {
const keyword = this.keyInp.value.trim().toLowerCase();
if (!keyword) return;
for (let i = 0; i < jobs.length; i++) {
const el = jobs[i];
const name = el
.querySelector(`[data-${this.prefix}-name]`)
.textContent.trim()
.toLowerCase();
if (!name.includes(keyword)) el.classList.add("hidden");
}
}
}
const setDropdown = new Dropdown();
const setFilter = new Filter();
const setPopover = new Popover();
const setTabs = new Tabs();
const setModal = new ServiceModal();
@ -1054,3 +1356,69 @@ const setFilterGlobal = new FilterSettings(
);
const setMultiple = new Multiple("services");
// Hide / Show no matching message on service modal
document
.querySelector("input#settings-filter")
.addEventListener("input", () => {
setTimeout(() => {
const tabs = document
.querySelector("[data-services-tabs-desktop]")
.querySelectorAll("[data-tab-handler]");
let isAllHidden = true;
for (let i = 0; i < tabs.length; i++) {
const plugin = tabs[i];
if (!plugin.classList.contains("hidden")) {
isAllHidden = false;
break;
}
}
const formEl = document.querySelector("[data-services-modal-form]");
const noMatchEl = document.querySelector("[data-services-nomatch]");
if (isAllHidden) {
noMatchEl.classList.remove("hidden");
formEl.classList.add("hidden");
}
if (!isAllHidden) {
formEl.classList.remove("hidden");
noMatchEl.classList.add("hidden");
}
}, 20);
});
// Hide / Show no matching message for services card
try {
document
.querySelector("input#service-name-keyword")
.addEventListener("input", () => {
setTimeout(() => {
const cards = document.querySelectorAll("[data-services-card]");
let isAllHidden = true;
for (let i = 0; i < cards.length; i++) {
const card = cards[i];
if (!card.classList.contains("hidden")) {
isAllHidden = false;
break;
}
}
const formEl = document.querySelector("[data-services-modal-form]");
const noMatchEl = document.querySelector(
"[data-services-nomatch-card]",
);
if (isAllHidden) {
noMatchEl.classList.remove("hidden");
formEl.classList.add("hidden");
}
if (!isAllHidden) {
formEl.classList.remove("hidden");
noMatchEl.classList.add("hidden");
}
}, 20);
});
} catch (e) {}

View file

@ -1,5 +1,25 @@
{% extends "base.html" %}
{% block content %}
{% set methods = ["all"] %}
{% set states = ["all", "draft", "online"] %}
{% set draft_count = [] %}
{% set online_count = [] %}
{% for services_batched in services|batch(3) %}
{% for service in
services_batched %}
{% if service['SERVER_NAME']['method'] not in methods %}
{% if methods.append(service['SERVER_NAME']['method']) %}{% endif %}
{% endif %}
{% if service.get('IS_DRAFT', '') == "yes" %}
{% if draft_count.append(1) %}{% endif %}
{% endif %}
{% if service.get('IS_DRAFT', '') == "no" %}
{% if online_count.append(1) %}{% endif %}
{% endif %}
{% endfor %}
{% endfor %}
{% set draft_count = draft_count|length %}
{% set online_count = online_count|length %}
<!-- actions -->
<div data-services-service
class="col-span-12 relative flex justify-center min-w-0 break-words rounded-2xl bg-clip-border">
@ -22,19 +42,150 @@
</div>
<!-- end actions -->
<!-- services container-->
<div class="p-0 my-4 sm:mx-4 md:px-4 grid grid-cols-12 col-span-12 lg:gap-x-4 relative min-w-0 break-words rounded-2xl bg-clip-border">
<div class="p-0 my-4 sm:mx-2 md:mx-4 md:px-4 grid grid-cols-12 col-span-12 md:gap-x-4 gap-y-4 relative min-w-0 break-words rounded-2xl bg-clip-border">
{% if services|length == 0 %}
<div class="col-span-12 sm:col-span-4 sm:col-start-5">
<div class="transition duration-300 ease-in-out dark:opacity-90 text-center relative w-full p-4 text-white bg-blue-500 rounded-lg">
No service to show
</div>
</div>
{% else %}
{% endif %}
{% if services|length >= 4 %}
<!-- info-->
{% set services_info = [
{"name" : "SERVICES TOTAL", "data" : services|length|string},
{"name" : "TOTAL DRAFT", "data" : draft_count|string},
{"name" : "TOTAL ONLINE", "data" : online_count|string},
] %}
<div class="h-fit col-span-12 md:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
{% for info in services_info %}
<div class="mx-1 flex items-center my-4">
<p class="transition duration-300 ease-in-out font-bold mb-0 font-sans text-sm leading-normal uppercase dark:text-gray-500 dark:opacity-80">
{{ info['name'] }}
</p>
<p class="transition duration-300 ease-in-out pl-2 col-span-1 mb-0 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-80">
{{ info['data'] }}
</p>
</div>
{% endfor %}
</div>
<!-- end info -->
<!-- filter -->
{% set filters = [
{
"type": "input",
"name": "Search",
"label": "search",
"id": "service-name-keyword",
"placeholder": "service name",
"pattern": "(.*?)"
},
{
"type": "select",
"name": "Method",
"id": "method",
"value": "all",
"values": methods
},
{
"type": "select",
"name": "State",
"id": "state",
"value": "all",
"values": states
}
] %}
<div data-services-filter
class="h-fit col-span-12 md:col-span-8 2xl:col-span-6 3xl:col-span-5 p-4 relative flex flex-col min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
<h5 class="mb-2 font-bold dark:text-white/90">FILTER</h5>
<div class="mx-2 grid grid-cols-12 gap-4">
{% for filter in filters %}
{% if filter['type'] == 'input' %}
<!-- search inpt-->
<div class="flex flex-col relative col-span-12 md:col-span-6">
<h5 class="my-1 transition duration-300 ease-in-out dark:opacity-90 text-sm sm:text-md font-bold m-0 dark:text-gray-300">
{{ filter['name'] }}
</h5>
<label for="{{ filter['id'] }}" class="sr-only">{{ filter['label'] }}</label>
<input type="text"
id="{{ filter['id'] }}"
name="{{ filter['id'] }}"
class="dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-3 py-1 font-normal text-gray-700 transition-all placeholder:text-gray-500"
placeholder="{{ filter['placeholder'] }}"
pattern="{{ filter['pattern'] }}"
required />
</div>
<!-- end search inpt-->
{% endif %}
{% if filter['type'] == 'select' %}
<!-- select -->
<div class="flex flex-col relative col-span-12 md:col-span-6">
<h5 class="my-1 transition duration-300 ease-in-out dark:opacity-90 text-sm sm:text-md font-bold m-0 dark:text-gray-300">
{{ filter['name'] }}
</h5>
<button aria-controls="filter-{{ filter['id'] }}"
data-services-setting-select="{{ filter['id'] }}"
class="disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left text-sm leading-5.6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500">
<span aria-description="current filter state value"
id="services-{{ filter['id'] }}"
data-name="services-{{ filter['id'] }}"
data-services-setting-select-text="{{ filter['id'] }}">all</span>
<!-- chevron -->
<svg data-services-setting-select="{{ filter['id'] }}"
class="transition-transform h-4 w-4 fill-gray-500"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512">
<path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z" />
</svg>
</button>
<!-- end chevron -->
<!-- dropdown-->
<div id="filter-{{ filter['id'] }}"
role="listbox"
data-services-setting-select-dropdown="{{ filter['id'] }}"
class="hidden z-100 absolute h-full flex-col w-full translate-y-16">
{% for value in filter['values'] %}
<button role="option"
data-services-setting-select-dropdown-btn="{{ filter['id'] }}"
value="{{ value }}"
class="{% if loop.first %}dark:bg-primary bg-primary text-gray-300 border-t rounded-t {% else %} bg-white {% endif %} {% if loop.last %}rounded-b{% endif %} border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300">
{{ value }}
</button>
{% endfor %}
</div>
<!-- end dropdown-->
</div>
<!-- end select -->
{% endif %}
{% endfor %}
</div>
</div>
<div data-services-nomatch-card
class="hidden w-full overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 col-span-12 p-4 relative break-words">
<div class="col-span-12 flex flex-col justify-center items-center h-fit">
<svg xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="mb-2 w-8 h-8 stroke-white">
<path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607ZM10.5 7.5v6m3-3h-6" />
</svg>
<h5 class="font-bold dark:text-white/90 mx-2 text-white">No settings match</h5>
</div>
</div>
{% endif %}
{% if services|length > 0 %}
<!-- end filter -->
{% for services_batched in services|batch(3) %}
{% for service in
services_batched %}
{% set id_server_name = service["SERVER_NAME"]['value'].replace(".", "-") %}
<div data-services-service="{{ service['SERVER_NAME']['value'] }}"
<div data-services-card data-services-service="{{ service['SERVER_NAME']['value'] }}"
class="my-2 dark:brightness-110 overflow-hidden hover:scale-102 transition col-span-12 lg:col-span-6 3xl:col-span-4 p-4 w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
<div data-services-settings
class="hidden"
@ -49,12 +200,12 @@
class="hidden"
data-value="{{ service['SERVER_NAME']['method'] }}"></div>
<div class="flex justify-between items-start">
<h5 class="transition duration-300 ease-in-out text-center sm:text-left mb-1 font-bold dark:text-white/90">
<h5 data-services-name="{{ service["SERVER_NAME"]['value'] }}" class="transition duration-300 ease-in-out text-center sm:text-left mb-1 font-bold dark:text-white/90">
{{ service["SERVER_NAME"]['value'] }}
</h5>
{% if service.get('IS_DRAFT', "no") == "yes" and service["SERVER_NAME"]['method'] in ["ui", "default"] %}
<button class="group relative">
<p class="dark:text-gray-300 -z-10 opacity-0 group-hover:z-10 group-hover:opacity-100 transition fixed bg-white dark:bg-slate-800 rounded right-12 px-1 py-0.5">
<p data-services-state="draft" class="dark:text-gray-300 -z-10 opacity-0 group-hover:z-10 group-hover:opacity-100 transition fixed bg-white dark:bg-slate-800 rounded right-12 px-1 py-0.5">
Draft
</p>
<svg xmlns="http://www.w3.org/2000/svg"
@ -66,7 +217,7 @@
</button>
{% else %}
<button class="group relative">
<p class="dark:text-gray-300 -z-10 opacity-0 group-hover:z-10 group-hover:opacity-100 transition fixed bg-white dark:bg-slate-800 rounded right-12 px-1 py-0.5">
<p data-services-state="online" class="dark:text-gray-300 -z-10 opacity-0 group-hover:z-10 group-hover:opacity-100 transition fixed bg-white dark:bg-slate-800 rounded right-12 px-1 py-0.5">
Online
</p>
<svg data-toggle-draft="false"
@ -79,7 +230,7 @@
</button>
{% endif %}
</div>
<h6 class="text-center sm:text-left mb-2 font-semibold text-gray-600 dark:text-white/80">
<h6 data-services-method="{{ service["SERVER_NAME"]['method'] }}" class="text-center sm:text-left mb-2 font-semibold text-gray-600 dark:text-white/80">
{{ service["SERVER_NAME"]['method'] }}
</h6>
{% set details = [

View file

@ -61,6 +61,20 @@
<!-- end search inpt-->
</div>
{% include "settings_tabs.html" %}
<div data-services-nomatch
class="hidden w-full overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 col-span-12 p-4 relative break-words">
<div class="col-span-12 flex flex-col justify-center items-center h-fit">
<svg xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="mb-2 w-8 h-8 dark:stroke-white/90 stroke-gray-800">
<path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607ZM10.5 7.5v6m3-3h-6" />
</svg>
<h5 class="font-bold dark:text-white/90 mx-2 text-gray-800">No settings match</h5>
</div>
</div>
<!-- new and edit form -->
<form data-services-modal-form
class="w-full h-full flex flex-col justify-between"

View file

@ -9,10 +9,11 @@ from selenium.common.exceptions import TimeoutException
from wizard import DRIVER
from base import TEST_TYPE
from utils import access_page, assert_alert_message, assert_button_click, safe_get_element, wait_for_service
from utils import access_page, assert_alert_message, assert_button_click, safe_get_element, wait_for_service, verify_select_filters
exit_code = 0
try:
log_info("Navigating to the services page ...")
access_page(DRIVER, "/html/body/aside[1]/div[1]/div[3]/ul/li[4]/a", "services")
@ -233,7 +234,70 @@ try:
log_error("The service is still working, exiting ...")
exit(1)
log_info("The service is not working, as expected, trying to delete it ...")
log_info("Create another service app3.example.com to get filters (need at least 4 services on page)")
assert_button_click(DRIVER, "//button[@data-services-action='new']")
server_name_input = safe_get_element(DRIVER, By.ID, "SERVER_NAME")
assert isinstance(server_name_input, WebElement), "Input is not a WebElement"
server_name_input.clear()
server_name_input.send_keys("app3.example.com")
access_page(DRIVER, "//button[@data-services-modal-submit='']", "services", False)
if TEST_TYPE == "linux":
wait_for_service("app3.example.com")
try:
services = safe_get_element(DRIVER, By.XPATH, "//div[@data-services-service]", multiple=True, error=True)
assert isinstance(services, list), "Services is not a list"
except TimeoutException:
log_exception("Services not found, exiting ...")
exit(1)
if len(services) < 4:
log_error(f"The service hasn't been created ({len(services)} services found), exiting ...")
exit(1)
server_name_elem = safe_get_element(DRIVER, By.XPATH, "//div[@data-services-service='app3.example.com']//h5")
assert isinstance(server_name_elem, WebElement), "Server name element is not a WebElement"
if server_name_elem.text.strip() != "app3.example.com":
log_error('The service "app3.example.com" is not present, exiting ...')
exit(1)
service_method_elem = safe_get_element(DRIVER, By.XPATH, "//div[@data-services-service='app3.example.com']//h6")
assert isinstance(service_method_elem, WebElement), "Service method element is not a WebElement"
if service_method_elem.text.strip() != "ui":
log_error("The service should have been created by the ui, exiting ...")
exit(1)
log_info("Service app3.example.com is present, trying filters...")
# Set keyword with no matching settings
keyword_no_match = "dqz48 é84 dzq 584dz5qd4"
btn_keyword = safe_get_element(DRIVER, "js", 'document.querySelector("button#service-name-keyword")')
btn_keyword.send_keys(keyword_no_match)
sleep(0.1)
# Check that the no matching element is shown and other card hide
is_no_match = DRIVER.execute_script('return document.querySelector("[data-services-nomatch-card]").classList.contains("hidden") ? false : true')
if not is_no_match:
log_error(f"Filter keyword with value {keyword_no_match} shouldn't match something.")
exit(1)
# Reset
btn_keyword.send_keys("")
# Test select filters
select_filters = [
{"name": "Method", "id": "method", "value": "all", "update_value": "123456"},
{"name": "State", "id": "state", "value": "all", "update_value": "123456"},
]
verify_select_filters(DRIVER, "services", select_filters)
log_info("Filters working as expected, trying to delete app2.example.com ...")
try:
delete_button = safe_get_element(DRIVER, By.XPATH, "//button[@data-services-action='delete' and @data-services-name='app2.example.com']", error=True)

View file

@ -167,18 +167,18 @@ def wait_for_service(service: str = "www.example.com"):
def verify_select_filters(driver, page_name: str, filter_items: list):
for item in filter_items:
# Update in order to get no match
driver.execute_script(f"document.querySelector('[data-{page_name}-setting-select-dropdown-btn=`{item['id']}`][value=`{item['value']}`]').setAttribute('value', '{item['update_value']}')")
select_btn = safe_get_element(driver, "js", f"document.querySelector('[data-{page_name}-setting-select-dropdown-btn=`{item['id']}`][value=`{item['update_value']}`]')")
driver.execute_script(f"document.querySelector('[data-{page_name}-setting-select-dropdown-btn={item['id']}][value={item['value']}]').setAttribute('value', '{item['update_value']}')")
select_btn = safe_get_element(driver, "js", f"document.querySelector('[data-{page_name}-setting-select-dropdown-btn={item['id']}][value={item['update_value']}]')")
select_btn.click()
# Verify
bans_hidden = safe_get_element(driver, "js", f'document.querySelectorAll("[data-{page_name}-list-item][class*=`hidden`]")')
bans_hidden = safe_get_element(driver, "js", f'document.querySelectorAll("[data-{page_name}-list-item][class*=hidden]")')
if len(bans_hidden) == 0:
log_error(f"The {item['name']} filter is not working, exiting ...")
exit(1)
# Reset
driver.execute_script(f"document.querySelector('[data-{page_name}-setting-select-dropdown-btn=`{item['id']}`][value=`{item['update_value']}`]').setAttribute('value', '{item['value']}')")
select_btn = safe_get_element(driver, "js", f"document.querySelector('[data-{page_name}-setting-select-dropdown-btn=`{item['id']}`][value=`{item['value']}`]')")
driver.execute_script(f"document.querySelector('[data-{page_name}-setting-select-dropdown-btn={item['id']}][value={item['update_value']}]').setAttribute('value', '{item['value']}')")
select_btn = safe_get_element(driver, "js", f"document.querySelector('[data-{page_name}-setting-select-dropdown-btn={item['id']}][value={item['value']}]')")
select_btn.click()
sleep(0.1)