> ## Documentation Index
> Fetch the complete documentation index at: https://docs.germainux.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 01/31/22 Release Notes

> Highlights of the GermainUX release of January 31, 2022, including automation features and monitoring and analytics updates.

> **[Bot (tips)](#automation-bot-tips)**
>
> Automation

> **[Application Crash RCA](#monitoring-%26-analytics-application-crash-rca)**
>
> Monitoring & Analytics

> **[Docker](#monitoring-%26-analytics-docker)**
>
> Monitoring & Analytics

## Automation - Bot (tips)

### Description

Here are some TIPs on using Germain’s bot (that is integrated with Selenium), all this to help avoid UX and Process issues.

While working with Selenium, a few scenarios can occur which can prevent the bot from performing as expected. Such scenarios are:

* Bot tries to perform an action before the webpage is fully loaded
* Bot tries to click on an element before it is ready to be interacted with

We can address these two scenarios by using Explicit wait function provided by Selenium. In order to declare explicit wait, we have to use “Expected Conditions” such as –

* AlertIsPresent()
* elementSelectionStateToBe()
* elementToBeClickable()
* elementToBeSelected()
* frameToBeAvaliableAndSwitchToIt()
* invisibilityOfTheElementLocated()

> **Show all 18**
>
> * invisibilityOfElementWithText()
> * presenceOfAllElementsLocatedBy()
> * presenceOfElementLocated()
> * textToBePresentInElement()
> * textToBePresentInElementLocated()
> * textToBePresentInElementValue()
> * titleIs()
> * titleContains()
> * visibilityOf()
> * visibilityOfAllElements()
> * visibilityOfAllElementsLocatedBy()
> * visibilityOfElementLocated()

We had a scenario where the synthetic Bot was failing inconsistently. The failure was hard to pin point as it never failed at the same part of the scenario each time.

This failure was caused because the Bot was trying to click on an element before it was in a ready state. This caused the following exception –

Exception in thread "main" org.openqa.selenium.ElementClickInterceptedException:

element click intercepted:

Element \<input value="Google Search" aria-label="Google Search" name="btnK" type="submit">

is not clickable at point (596, 368).

Other element would receive the click: \<span>...\</span>

### Root-cause of the issue

This snippet of code was responsible for causing this inconsistent behavior

wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//a\[text()='Overview']")));

### Solution

The following code resolved this issue

wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a\[text()='Overview']")));

This new code is more stable because it waits for the element to be clickable before it tries to perform an action on it.

### Complete Solution - Full Synthetic Scenario

```java theme={null}
import java.io.File;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogType;
import java.text.SimpleDateFormat;
import java.util.Date;
//Login
driver.manage().deleteAllCookies();
WebDriverWait wait = new WebDriverWait(driver,120);
log.info("URL - {}", context.resolveConfigurationReference("url"));
driver.get(context.resolveConfigurationReference("url"));
driver.manage().window().maximize();
JavascriptExecutor js = ((JavascriptExecutor) driver);
// Login Screen
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@id='identifierInput']")));
//Fill username and password
driver.findElement(By.xpath("//*[@id='identifierInput']")).sendKeys(context.resolveConfigurationReference("Call Center User").username);
log.info("Username entered");
//Click next button
driver.findElement(By.xpath("//*[@id='post-button']")).click();
//Fill password
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@id='password']")));
driver.findElement(By.xpath("//*[@id='password']")).sendKeys(credentials.password.value);
log.info( "Password entered") ;
//Click Login Button
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@id='remember-me-login-button']")));
driver.findElement(By.xpath("//*[@id='remember-me-login-button']")).click();
log.info("Login button clicked");
//Wait for home to load
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body/div[1]/div/div[4]/div/div/div[1]/div[2]/ul/li/a")));
//Click ProdiGE tab
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body/div[1]/div/div[4]/div/div/div[1]/div[1]/ul/li[11]/a")));
driver.findElement(By.xpath("/html/body/div[1]/div/div[4]/div/div/div[1]/div[1]/ul/li[11]/a")).click();
log.info("ProdiGE tab clicked");
//Verify ProiGE Screenhas loaded
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[text()='Overview']")));
//Click Equipment Id field
element = driver.findElement(By.xpath("//*[@placeholder='Equipment Id']"));
js.executeScript("arguments[0].click();", element);
log.info("Equipment Id field clicked");
//Enter Equipment Id - System ID
driver.findElement(By.xpath("//*[@placeholder='Equipment Id']")).sendKeys(context.resolveConfigurationReference("systemId"));
log.info("Entered Equipment Id");
//Click Search by System Id
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@title='Search Center:Search System Id']")));
element = driver.findElement(By.xpath("//*[@title='Search Center:Search System Id']"));
js.executeScript("arguments[0].click();", element);
log.info("Clicked Search by System Id");
////////////////////////////// Save for later \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// //Enter Equipment Id - Serial #
// driver.findElement(By.xpath("//*[@placeholder='Equipment Id']")).sendKeys(context.resolveConfigurationReference("Serial Number"));
// log.info("Entered Equipment Id");
// //Click Search by Serial #
// wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@title='Search Center:Search Serial #']")));
// element = driver.findElement(By.xpath("//*[@title='Search Center:Search Serial #']"));
// js.executeScript("arguments[0].click();", element);
// log.info("Clicked Search by Serial #");
////////////////////////////// Save for later \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//Wait for search to complete
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@id='left-arrow']/i")));
//Click Create SR
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@title='Assets:Create SR']")));
driver.findElement(By.xpath("//*[@title='Assets:Create SR']")).click();
log.info("Clicked Create SR");
//Click New Button
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@title='Service Request:New']")));
driver.findElement(By.xpath("//*[@title='Service Request:New']")).click();
log.info("Clicked New Button");
Thread.sleep(1000);
//Click SR Type dropdown
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@aria-label='SR Type']/following-sibling::span")));
// driver.findElement(By.xpath("//*[@aria-label='SR Type']/following-sibling::span")).click();
element = driver.findElement(By.xpath("//*[@aria-label='SR Type']/following-sibling::span"));
Actions actions = new Actions(driver);
actions.moveToElement(element).click().build().perform();
// element = driver.findElement(By.xpath("//*[@aria-label='SR Type']/following-sibling::span"));
// js.executeScript("arguments[0].click();", element);
log.info("Clicked SR Type dropdown ");
//Enter input in SR Type
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//ul[@class='ui-menu ui-widget ui-widget-content ui-autocomplete ui-front']/descendant::div[text()='Corrective Repair']")));
driver.findElement(By.xpath("//ul[@class='ui-menu ui-widget ui-widget-content ui-autocomplete ui-front']/descendant::div[text()='Corrective Repair']")).click();
log.info("Entered input in SR Type");
//Enter value in problem description
element = driver.findElement(By.xpath("//*[@aria-label='Problem Description']"));
driver.findElement(By.xpath("//*[@aria-label='Problem Description']")).click();
driver.findElement(By.xpath("//*[@aria-label='Problem Description']")).sendKeys("Germain RPA Test");
log.info("Entered value in problem description");
Thread.sleep(1000);
//Click contacts icon
driver.findElement(By.xpath("//*[@aria-label='Selectable Contact']/following-sibling::span")).click();
log.info("Clicked contacts icon");
//Wait for contacts applet to load
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@title='Add Contacts:Affiliated Contacts']")));
log.info("Contacts applet loaded");
//Click on All Contacts
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[contains(@title,'Add Contacts:All Contacts')]")));
driver.findElement(By.xpath("//*[contains(@title,'Add Contacts:All Contacts')]")).click();
log.info("Clicked on All Contacts");
Thread.sleep(2000);
//Click on Query
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[contains(@title,'Add Contacts:Query')]")));
driver.findElement(By.xpath("//*[contains(@title,'Add Contacts:Query')]")).click();
log.info("Clicked on Query");
// wait.until(ExpectedConditions.alertIsPresent()).dismiss();
// driver.switchTo().alert().dismiss();
// js.executeScript("window.alert = function() {};");
//Type in Last Name
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("(//input[contains(@name,'Last_Name')])")));
driver.findElement(By.xpath("(//input[contains(@name,'Last_Name')])")).click();
driver.findElement(By.xpath("(//input[contains(@name,'Last_Name')])")).sendKeys(context.resolveConfigurationReference("lastName"));
log.info("Typed in Last Name");
//Type in First Name
driver.findElement(By.xpath("(//*[contains(@aria-roledescription,'First Name')])")).click();
driver.findElement(By.xpath("(//*[contains(@name,'First_Name')])")).sendKeys(context.resolveConfigurationReference("firstName"));
log.info("Typed in First Name");
//Click on Go
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("(//*[contains(@title,'Add Contacts:Go')])")));
driver.findElement(By.xpath("(//*[contains(@title,'Add Contacts:Go')])")).click();
log.info("Clicked on Go");
Thread.sleep(2000);
//Click on Add Contact
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//div[@class='siebui-popup-btm siebui-mvg-btn-modifier']/descendant::button[@title='Contacts:Add >']")));
driver.findElement(By.xpath("//div[@class='siebui-popup-btm siebui-mvg-btn-modifier']/descendant::button[@title='Contacts:Add >']")).click();
log.info("Clicked on Add Contact");
Thread.sleep(1000);
//Click on Ok
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//div[@class='siebui-popup-btm siebui-mvg-btn-modifier']/descendant::button[@title='Contacts:OK']")));
driver.findElement(By.xpath("//div[@class='siebui-popup-btm siebui-mvg-btn-modifier']/descendant::button[@title='Contacts:OK']")).click();
log.info("Clicked on Ok");
//Select safety concern
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body/div[1]/div/div[6]/div/div[7]/div/div[1]/div[3]/div[2]/div/form/div/span/div[3]/div/div/table/tbody/tr[8]/td[2]/div/span")));
driver.findElement(By.xpath("/html/body/div[1]/div/div[6]/div/div[7]/div/div[1]/div[3]/div[2]/div/form/div/span/div[3]/div/div/table/tbody/tr[8]/td[2]/div/span")).click();
log.info("Safety concern drop down clicked");
//Select None reported
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//li[@class='ui-menu-item']/descendant::div[text()='None Reported']")));
driver.findElement(By.xpath("//li[@class='ui-menu-item']/descendant::div[text()='None Reported']")).click();
log.info("None Reported clicked");
//Click on Equipment status radio button
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[contains(@aria-label,'Equipment Status System Up')]")));
driver.findElement(By.xpath("//*[contains(@aria-label,'Equipment Status System Up')]")).click();
log.info("Clicked on Equipment status radio button");
Thread.sleep(2000);
//Click menu button
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[contains(@aria-label,'Service Request:Menu')]")));
element = driver.findElement(By.xpath("//*[contains(@aria-label,'Service Request:Menu')]"));
js.executeScript("arguments[0].click();", element);
log.info("Clicked on menu button");
Thread.sleep(1000);
//Click on save button
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//ul[@class='siebui-appletmenu ui-menu ui-widget ui-widget-content']/descendant::li[@data-caption='Save Record                [Ctrl+S]']")));
driver.findElement(By.xpath("//ul[@class='siebui-appletmenu ui-menu ui-widget ui-widget-content']/descendant::li[@data-caption='Save Record                [Ctrl+S]']")).click();
log.info("Clicked on save button");
Thread.sleep(5000);
//Save SR #
String srNumber = driver.findElement(By.xpath("//div[@class='siebui-btn-grp-applet']/descendant::input[@aria-label='SR #']")).getAttribute("value");
log.info("SR # - {}", srNumber);
transaction.pid = srNumber;
Thread.sleep(3000);
//Click on Activity new button
Thread.sleep(3000);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[contains(@aria-label,'Dispatch:New')]/span")));
// driver.findElement(By.xpath("//*[contains(@aria-label,'Dispatch:New')]")).click();
element = driver.findElement(By.xpath("//*[contains(@aria-label,'Dispatch:New')]"));
actions = new Actions(driver);
actions.moveToElement(element).click().build().perform();
log.info("New Activity record");
Thread.sleep(5000);
// //Click Activity type drop down
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@aria-label='Activity Type']/following-sibling::span")));
driver.findElement(By.xpath("//*[@aria-label='Activity Type']/following-sibling::span")).click();
log.info("Clicked Activity type drop down");
Thread.sleep(2000);
// //Click Activity type field support
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//ul[@class='ui-menu ui-widget ui-widget-content ui-autocomplete ui-front']/descendant::div[text()='Field Support']")));
driver.findElement(By.xpath("//ul[@class='ui-menu ui-widget ui-widget-content ui-autocomplete ui-front']/descendant::div[text()='Field Support']")).click();
// //Click Activity status drop down
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@aria-label='Activity Status']/following-sibling::span")));
driver.findElement(By.xpath("//*[@aria-label='Activity Status']/following-sibling::span")).click();
log.info("Clicked Activity status drop down");
Thread.sleep(1000);
//Click Activity status open
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//ul[@class='ui-menu ui-widget ui-widget-content ui-autocomplete ui-front']/descendant::div[text()='Open']")));
driver.findElement(By.xpath("//ul[@class='ui-menu ui-widget ui-widget-content ui-autocomplete ui-front']/descendant::div[text()='Open']")).click();
log.info("Clicked Activity status Open");
// //Click Save Activity
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[contains(@aria-label,'Dispatch:Save')]")));
driver.findElement(By.xpath("//*[contains(@aria-label,'Dispatch:Save')]")).click();
log.info("Clicked on Save Activity");
Thread.sleep(10000);
//Save Activity # to file
String activityNumber = driver.findElement(By.xpath("//div[@class='siebui-btn-grp-applet']/descendant::input[@aria-label='Activity']")).getAttribute("value");
log.info("Activity # - {}", activityNumber);
transaction.tid = activityNumber;
FileUtils.writeStringToFile(new File("activity-number.txt"), activityNumber);
// //Click on Call Management tab
Thread.sleep(5000);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[contains(text(),'Call Management')]")));
// driver.findElement(By.xpath("//*[contains(text(),'Call Management')]")).click();
element = driver.findElement(By.xpath("//*[contains(text(),'Call Management')]"));
js.executeScript("arguments[0].click();", element);
log.info("Clicked on Call Management tab");
Thread.sleep(2000);
// //Wait for Call Management tab to load
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[contains(text(),'Unscheduled TS Activities')]")));
log.info("Wait for Call Management tab to load");
// //Click Service Request tab
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body/div[1]/div/div[4]/div/div/div[1]/div[1]/ul/li[7]")));
driver.findElement(By.xpath("/html/body/div[1]/div/div[4]/div/div/div[1]/div[1]/ul/li[7]")).click();
log.info("Clicked on Service Reuest tab");
// //Click on SR Dashboard
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[contains(text(),'SR Dashboard')]")));
driver.findElement(By.xpath("//*[contains(text(),'SR Dashboard')]")).click();
log.info("Clicked on SR Dashboard");
//Wait for SR Dashboard to load.
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//div[@class='siebui-applet siebui-collapsible-applet siebui-list Selected siebui-active siebui-applet-active siebui-hilight']/descendant::span[text()='New Field Support Activities']")));
log.info("SR Dashboard to loaded");
Thread.sleep(2000);
```

## Monitoring & Analytics - Application Crash RCA

### Description

In my 25 years of experience, I have seen plenty of applications crashing—sometimes hundreds of times a day. Some of these crashes impact a business quite significantly, while some don’t. Either way, many of these crashes aren’t reported because users are too busy and can work around them. In the meantime, user experience degrades and business losses increase.

It takes days—and sometimes even weeks—to analyze the business impact of hundreds of application crashes, making it nearly impossible. An application restart is often the easy ‘solution,’ but that’s not enough.

**Severe business impact? Or can it be ignored?** \
&#x20;Germain can help save significant RCA time by automatically reporting the number of user and/or business processes that are affected by application crashes. That way, your Ops team can focus on the crashes that are critical to your business.

**Recurring or new?** \
&#x20;Germain can help save significant analysis time by automatically analyzing and distinguishing crashes that occurred before, crashes that the development team is actively trying to fix, and the crashes that are “new”/have never been seen before. This allows your Devops teams to focus on analyzing the new problems that are critical to the business. This is very handy when dealing with hundreds of crashes per day.

### Benefit

Significantly improve UX and Process performance by finding within minutes (instead of months) critical Application Crashes that affect the business the most, and finding their root-cause, which in turns improve Customer Experience, Retention or Sales.

### Configuration

[Categorization](https://docs.germainux.com/main/data-categorization.md)

## Monitoring & Analytics - Docker

### Description

If, like many organizations, you are leveraging Docker, you are likely facing a number of new challenges as you try to scale your organization with it. Germain can now help proactively detect performance issues before the issues impact your business. Germain can also help troubleshoot issues in real-time via a number of new mechanisms in the areas of synthetic, predictive, and reactive real-time monitoring.

Docker-related KPI currently preconfigured in Germain:

* Volume Events (via Drool file, HTTP Log)
* Container
* Network monitoring (via Docker’s rest api)
* Disk monitoring(via Docker’s rest api)
* Components monitoring(via Docker’s rest api)
* Files Creation monitoring(via Docker’s rest api)
* Profiles Creation(via Docker’s rest api)

![01/31/22 Release Notes: Monitoring & Analytics - Docker](https://mintcdn.com/germain-ux/8KX3c-GSSWR99tdN/images/main/docker-monitoring/image-20220202-205414.png?fit=max\&auto=format\&n=8KX3c-GSSWR99tdN\&q=85\&s=1a1aa73ccbda9b97d98971052e5d682d)

### Configuration

[Docker Observability](https://docs.germainux.com/main/docker-monitoring.md)

## Get Help

> **[Contact GermainUX Support](https://docs.germainux.com/main/support.md)**
>
> The Germain Team can help you set this up.

> **Can't find what you need?**
>
> Search all GermainUX docs with **Ctrl + K**, or use the feedback buttons at the bottom of this page to tell us what is missing.

The content of this document is proprietary to GERMAIN SOFTWARE.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.