Updated script that can be controled by Nodejs web app
This commit is contained in:
@@ -0,0 +1,279 @@
|
||||
import time
|
||||
import openpyxl
|
||||
import os
|
||||
import csv
|
||||
import pexpect
|
||||
import re
|
||||
from PIL import Image
|
||||
import pytesseract
|
||||
from selenium import webdriver
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.common.keys import Keys
|
||||
from selenium.webdriver.chrome.service import Service
|
||||
from selenium.webdriver.chrome.options import Options
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
from selenium.webdriver.chrome.service import Service
|
||||
from selenium.webdriver.chrome.options import Options
|
||||
from selenium.common.exceptions import TimeoutException, NoSuchElementException, ElementClickInterceptedException
|
||||
from selenium.webdriver.common.action_chains import ActionChains
|
||||
from webdriver_manager.chrome import ChromeDriverManager
|
||||
|
||||
def create_ssh_tunnel(dcu_ip, ssh_user="callysta_icon", ssh_host="10.232.4.113", ssh_port=21112, ssh_password="Callysta_icon2024!"):
|
||||
ssh_command = f"ssh -L 8888:{dcu_ip}:80 {ssh_user}@{ssh_host} -p {ssh_port}"
|
||||
child = pexpect.spawn(ssh_command)
|
||||
try:
|
||||
# Expect the password prompt and send the password
|
||||
child.expect("callysta_icon@10.232.4.113's password: ", timeout=60)
|
||||
child.sendline(ssh_password)
|
||||
child.expect(pexpect.EOF)
|
||||
print("SSH tunnel established.")
|
||||
except pexpect.exceptions.EOF:
|
||||
print("Error: SSH connection failed.")
|
||||
except pexpect.exceptions.TIMEOUT:
|
||||
print("Error: SSH connection timed out.")
|
||||
|
||||
if child.isalive():
|
||||
print("SSH tunnel is active.")
|
||||
else:
|
||||
print("Warning: SSH tunnel may not be active.")
|
||||
|
||||
return child # Return the child process to keep the tunnel open
|
||||
|
||||
def wait_for_page_to_load(driver, timeout=30):
|
||||
"""Wait for the page to completely load."""
|
||||
try:
|
||||
WebDriverWait(driver, timeout).until(
|
||||
lambda d: d.execute_script("return document.readyState") == "complete"
|
||||
)
|
||||
print("Halaman berhasil dimuat sepenuhnya.")
|
||||
except TimeoutException:
|
||||
raise Exception("Timeout menunggu halaman selesai dimuat.")
|
||||
|
||||
def click_running_state_tab(driver):
|
||||
"""Ensure the 'Running State' tab is clickable and click it."""
|
||||
try:
|
||||
running_state_tab = WebDriverWait(driver, 10).until(
|
||||
EC.presence_of_element_located((By.ID, "running-state"))
|
||||
)
|
||||
driver.execute_script("arguments[0].scrollIntoView(true);", running_state_tab)
|
||||
|
||||
WebDriverWait(driver, 10).until(
|
||||
EC.element_to_be_clickable((By.ID, "running-state"))
|
||||
)
|
||||
|
||||
# Periksa apakah tab sudah aktif
|
||||
if "sun-navbar_item is-active" not in running_state_tab.get_attribute("class"):
|
||||
running_state_tab.click()
|
||||
print("Tab 'Running State' diklik.")
|
||||
else:
|
||||
print("Tab 'Running State' sudah aktif.")
|
||||
except TimeoutException:
|
||||
print("Timeout menunggu tab 'Running State' untuk dapat diklik.")
|
||||
raise Exception("Tab 'Running State' tidak dapat diklik.")
|
||||
except Exception as e:
|
||||
print(f"Error clicking the 'Running State' tab: {e}")
|
||||
raise
|
||||
|
||||
def extract_text_and_verify(dcu_ip, expected_ip):
|
||||
# Path to the directory and file name based on expected IP
|
||||
screenshot_path = f"/Users/macos/Documents/SINDIGILIVE/CLIENTS/ICON+/Project-HES/Update_DCU/evidence/{dcu_ip}.png"
|
||||
csv_path = "/Users/macos/Documents/SINDIGILIVE/CLIENTS/ICON+/Project-HES/Update_DCU/extract_log.csv"
|
||||
status = "Failed"
|
||||
dcu_id = "Not found"
|
||||
|
||||
try:
|
||||
# Load the image
|
||||
image = Image.open(screenshot_path)
|
||||
print(f"Tangkapan layar dibuka: {screenshot_path}")
|
||||
|
||||
# Extract text from the image using Tesseract
|
||||
extracted_text = pytesseract.image_to_string(image)
|
||||
print("Extracted Text:")
|
||||
print(extracted_text)
|
||||
|
||||
# Search for the DCU ID using regex for a 14-digit sequence
|
||||
dcu_id_match = re.search(r'\b\d{14}\b', extracted_text)
|
||||
if dcu_id_match:
|
||||
dcu_id = dcu_id_match.group(0)
|
||||
print(f"DCU ID found: {dcu_id}")
|
||||
else:
|
||||
print("DCU ID not found in extracted text.")
|
||||
|
||||
# Verify if expected IP and "Success" are in the extracted text
|
||||
if expected_ip in extracted_text and "Success" in extracted_text:
|
||||
status = "Success"
|
||||
print(f"Found: {expected_ip} and Success")
|
||||
else:
|
||||
print(f"{expected_ip} atau status 'Success' tidak ditemukan dalam teks yang diekstrak.")
|
||||
|
||||
except FileNotFoundError:
|
||||
print(f"Tangkapan layar tidak ditemukan di {screenshot_path}")
|
||||
status = "Screenshot not found"
|
||||
|
||||
return dcu_id, status
|
||||
|
||||
def verify_dcu_update(driver, expected_ip, dcu_ip, retries=3):
|
||||
"""Verify if the DCU update is successful by checking the IP and connection state."""
|
||||
save_directory = "/Users/macos/Documents/SINDIGILIVE/CLIENTS/ICON+/Project-HES/Update_DCU/evidence"
|
||||
os.makedirs(save_directory, exist_ok=True) # Create the folder if it doesn’t exist
|
||||
screenshot_path = os.path.join(save_directory, f"{dcu_ip}.png")
|
||||
|
||||
# Full XPath dari elemen target
|
||||
full_xpath = '/html/body/div[1]/div/div[2]/div[2]/div[1]/div/div[1]/div[2]'
|
||||
|
||||
for attempt in range(retries):
|
||||
try:
|
||||
print(f"Attempt {attempt + 1} to verify DCU update...")
|
||||
|
||||
# Wait until the page is fully loaded
|
||||
WebDriverWait(driver, 15).until(lambda d: d.execute_script("return document.readyState") == "complete")
|
||||
print("Page fully loaded.")
|
||||
|
||||
# Switch to iframe
|
||||
iframe = driver.find_element(By.ID, 'home_content_iframe')
|
||||
driver.switch_to.frame(iframe)
|
||||
|
||||
# Wait for the presence of the element
|
||||
element = WebDriverWait(driver, 30).until(
|
||||
EC.presence_of_element_located((By.XPATH, full_xpath))
|
||||
)
|
||||
print("Target element is present.")
|
||||
|
||||
# Get the text from the element
|
||||
actual_text = element.text
|
||||
print(f"Found text: {actual_text}")
|
||||
|
||||
# Check if the text matches the desired IP
|
||||
if actual_text == expected_ip:
|
||||
print(f"DCU update verification successful: {actual_text}")
|
||||
|
||||
# Take a screenshot
|
||||
screenshot_taken = driver.save_screenshot(screenshot_path)
|
||||
if screenshot_taken:
|
||||
print(f"Screenshot saved at: {screenshot_path}")
|
||||
else:
|
||||
print("Failed to take screenshot. Check WebDriver setup.")
|
||||
|
||||
# Exit the loop if successful
|
||||
return
|
||||
|
||||
else:
|
||||
print(f"Text does not match expected value. Expected: {expected_ip}, Found: {actual_text}")
|
||||
raise Exception("Verification failed due to mismatched text.")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error during attempt {attempt + 1}: {e}")
|
||||
|
||||
# Refresh the page on error
|
||||
print("Page or data not found, attempting to refresh the page...")
|
||||
driver.switch_to.default_content() # Return to the main context before refreshing
|
||||
driver.refresh()
|
||||
time.sleep(5) # Wait a bit before retrying
|
||||
|
||||
# If all attempts fail, raise an exception
|
||||
raise Exception(f"Failed to verify DCU update after {retries} attempts.")
|
||||
|
||||
def update_dcu_ip(excel_file, log_file):
|
||||
# Load the Excel file
|
||||
wb = openpyxl.load_workbook(excel_file)
|
||||
sheet = wb.active
|
||||
|
||||
# Open log file for writing header only
|
||||
with open(log_file, "w", newline="") as log:
|
||||
writer = csv.writer(log)
|
||||
writer.writerow(["DCU IP", "DCU ID", "Updated IP", "Update Status"]) # Write CSV header
|
||||
|
||||
for row in range(2, sheet.max_row + 1):
|
||||
# Get the DCU IP from Excel and handle None values
|
||||
cell_value = sheet.cell(row=row, column=5).value
|
||||
if cell_value is None:
|
||||
print(f"Row {row}: DCU IP is empty. Skipping...")
|
||||
writer.writerow(["Not found", "Not found", "Not found", "Failed - Empty IP"])
|
||||
continue # Skip this row
|
||||
|
||||
dcu_ip = str(cell_value).strip('="')
|
||||
print(f"Processing DCU IP: {dcu_ip}")
|
||||
|
||||
# Set up SSH tunnel for each DCU IP
|
||||
ssh_password = "Callysta_icon2024!"
|
||||
ssh_process = create_ssh_tunnel(dcu_ip, ssh_password=ssh_password)
|
||||
|
||||
# Set up Chrome WebDriver for each DCU IP
|
||||
chrome_options = Options()
|
||||
chrome_options.binary_location = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
|
||||
chrome_options.add_argument("--headless")
|
||||
chrome_options.add_argument("--disable-gpu")
|
||||
chrome_options.add_argument("--no-sandbox")
|
||||
chrome_options.add_argument("--disable-dev-shm-usage")
|
||||
|
||||
driver_path = "/Users/macos/Documents/SINDIGILIVE/CLIENTS/ICON+/Project-HES/Update_DCU/chromedriver/chromedriver"
|
||||
driver = webdriver.Chrome(service=Service(driver_path), options=chrome_options)
|
||||
|
||||
try:
|
||||
# Access the DCU web application and login
|
||||
driver.get("http://localhost:8888")
|
||||
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "username")))
|
||||
driver.find_element(By.ID, "username").send_keys("admin")
|
||||
driver.find_element(By.ID, "password").send_keys("jh1296")
|
||||
driver.find_element(By.ID, "submit_btn").click()
|
||||
|
||||
# Wait for "parameter-setting" element and click
|
||||
WebDriverWait(driver, 20).until(
|
||||
EC.element_to_be_clickable((By.ID, "parameter-setting"))
|
||||
).click()
|
||||
|
||||
# Handle iframe if needed
|
||||
iframes = driver.find_elements(By.TAG_NAME, "iframe")
|
||||
if iframes:
|
||||
driver.switch_to.frame(iframes[0])
|
||||
|
||||
# Update the MDC IP
|
||||
new_ip = "10.232.107.250:9032"
|
||||
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "main_ip")))
|
||||
ip_field = driver.find_element(By.ID, "main_ip")
|
||||
dcu_id = "Not found"
|
||||
|
||||
# Clear the field and set the new IP
|
||||
for _ in range(3):
|
||||
ip_field.clear()
|
||||
current_value = ip_field.get_attribute("value").strip()
|
||||
if current_value == "":
|
||||
break
|
||||
time.sleep(2)
|
||||
else:
|
||||
raise Exception("Failed to clear the IP field!")
|
||||
|
||||
# Enter the new IP and submit
|
||||
ip_field.send_keys(new_ip)
|
||||
time.sleep(2)
|
||||
driver.find_element(By.ID, "main_host_submit").click()
|
||||
time.sleep(2)
|
||||
|
||||
# Verification step
|
||||
driver.back()
|
||||
wait_for_page_to_load(driver)
|
||||
click_running_state_tab(driver)
|
||||
verify_dcu_update(driver, expected_ip=new_ip, dcu_ip=dcu_ip)
|
||||
|
||||
# Log success
|
||||
dcu_id, status = extract_text_and_verify(dcu_ip, new_ip)
|
||||
writer.writerow([dcu_ip, dcu_id, new_ip, status])
|
||||
|
||||
except TimeoutException as e:
|
||||
print(f"Timeout error for DCU IP {dcu_ip}: {e}")
|
||||
writer.writerow([dcu_ip, "Not found", "Not found", "Failed - Timeout"])
|
||||
except Exception as e:
|
||||
print(f"Error processing DCU IP {dcu_ip}: {e}")
|
||||
writer.writerow([dcu_ip, "Not found", "Not found", "Failed - Error"])
|
||||
finally:
|
||||
# Ensure each SSH session and driver instance is closed after processing
|
||||
if ssh_process.isalive():
|
||||
ssh_process.terminate()
|
||||
driver.quit() # Close the WebDriver instance
|
||||
|
||||
# Main function
|
||||
if __name__ == "__main__":
|
||||
excel_file = "/Users/macos/Documents/SINDIGILIVE/CLIENTS/ICON+/Project-HES/Update_DCU/DCU-LIST.xlsx"
|
||||
log_file = "/Users/macos/Documents/SINDIGILIVE/CLIENTS/ICON+/Project-HES/Update_DCU/update_log.csv"
|
||||
update_dcu_ip(excel_file, log_file)
|
||||
Reference in New Issue
Block a user