Adding the chrome client for tests.
parent
dff77d4891
commit
33adb097f7
|
@ -0,0 +1,324 @@
|
|||
import json
|
||||
import os
|
||||
import urllib
|
||||
from typing import List
|
||||
|
||||
import requests
|
||||
|
||||
class Chrome:
|
||||
"""
|
||||
## Instância do Chrome
|
||||
---
|
||||
Esta classe utiliza o serviço "svc_chrome.exe" para fazer manipulações no navegador.
|
||||
|
||||
Ela mapeia o robo através da propriedade rid.
|
||||
|
||||
"EP" significa endpoint, e aponta para o endereco na web on se hostea o serviço, por padrão é:
|
||||
|
||||
https://localhost:8443
|
||||
"""
|
||||
|
||||
ep: str = ""
|
||||
|
||||
def __init__(self):
|
||||
self.ep = "https://localhost:8443"
|
||||
|
||||
def __request_get__(self, data: str):
|
||||
|
||||
"""
|
||||
## HTTP GET
|
||||
---
|
||||
Este método é responsável por realizar requisições HTTP do tipo GET.
|
||||
|
||||
Ele retorna o corpo de resposta da requisição, ou uma mensagem de erro, que indica qual foi a irregularidade ocorrida ao chamar a API.
|
||||
"""
|
||||
|
||||
url = self.ep + data
|
||||
print("Calling: " + url)
|
||||
|
||||
apikey = os.environ.get('REPLAY_APIKEY')
|
||||
headers = {"X-API-KEY": apikey}
|
||||
res = requests.get(url, headers=headers, verify=False)
|
||||
|
||||
if res.status_code >= 400:
|
||||
raise Exception(f"HTTP ERROR: {str(res.status_code)} - {res.text}")
|
||||
if res.headers.get("Content-Type") != None and res.headers.get("Content-Type").find("json") != -1:
|
||||
return json.loads(res.text)
|
||||
else:
|
||||
return res.text
|
||||
|
||||
def __request_json_get__(self, data: str):
|
||||
|
||||
"""
|
||||
## HTTP JSON GET
|
||||
---
|
||||
Este método é responsável por realizar requisições HTTP do tipo GET para objetos JSON.
|
||||
|
||||
Ele retorna o corpo de resposta da requisição, ou uma mensagem de erro, que indica qual foi a irregularidade ocorrida ao chamar a API.
|
||||
|
||||
---
|
||||
###### Obs: É uma função provisória, feita exclusivamente para o método open_tabs, já que o HEADER do corpo de resposta da requisição tem o atributo "Content-Type" com o valor "text/plain", ao invés de "application/json" como deveria ser.
|
||||
"""
|
||||
|
||||
url = self.ep + data
|
||||
print("Calling: " + url)
|
||||
|
||||
apikey = os.environ.get('REPLAY_APIKEY')
|
||||
headers = {"X-API-KEY": apikey}
|
||||
res = requests.get(url, headers=headers, verify=False)
|
||||
|
||||
if res.status_code >= 400:
|
||||
raise Exception(f"HTTP ERROR: {str(res.status_code)} - {res.text}")
|
||||
else:
|
||||
return res.json()
|
||||
|
||||
def __request_json_post__(self, path: str, object: dict):
|
||||
|
||||
"""
|
||||
## HTTP JSON POST
|
||||
---
|
||||
Este método é responsável por realizar requisições HTTP do tipo POST para objetos JSON.
|
||||
|
||||
Ele retorna o corpo de resposta da requisição, ou uma mensagem de erro, que indica qual foi a irregularidade ocorrida ao chamar a API.
|
||||
"""
|
||||
|
||||
url = self.ep + path
|
||||
print("Calling: " + url)
|
||||
|
||||
apikey = os.environ.get('REPLAY_APIKEY')
|
||||
headers = {"X-API-KEY": apikey}
|
||||
res = requests.post(url, json = object, headers = headers, verify = False)
|
||||
|
||||
if res.status_code >= 400:
|
||||
raise Exception(f"HTTP ERROR: {str(res.status_code)} - {res.text}")
|
||||
if res.headers.get("Content-Type") != None and res.headers.get("Content-Type").find("json") != -1:
|
||||
return json.loads(res.text)
|
||||
else:
|
||||
return res.text
|
||||
|
||||
def __request_raw_post__(self, path: str, data: str):
|
||||
|
||||
"""
|
||||
## HTTP RAW POST
|
||||
---
|
||||
Este método é responsável por realizar requisições HTTP do tipo POST para objetos RAW.
|
||||
|
||||
Ele retorna o corpo de resposta da requisição, ou uma mensagem de erro, que indica qual foi a irregularidade ocorrida ao chamar a API.
|
||||
"""
|
||||
|
||||
url = self.ep + path
|
||||
print("Calling: " + url)
|
||||
|
||||
apikey = os.environ.get('REPLAY_APIKEY')
|
||||
headers = {"X-API-KEY": apikey}
|
||||
res = requests.post(url, data = data, headers = headers, verify = False)
|
||||
|
||||
if res.status_code >= 400:
|
||||
raise Exception(f"HTTP ERROR: {str(res.status_code)} - {res.text}")
|
||||
if res.headers.get("Content-Type") != None and res.headers.get("Content-Type").find("json") != -1:
|
||||
return json.loads(res.text)
|
||||
else:
|
||||
return res.text
|
||||
|
||||
def start (self, to: int = 120):
|
||||
"""
|
||||
## Chrome Start
|
||||
Inicia uma nova sessão/instância do Google Chrome na máquina.
|
||||
|
||||
---
|
||||
#### IMPORTANTE:
|
||||
É um erro comum já estar com o Google Chrome aberto para realizar outras tarefas enquanto programa. Porém, para que este método funcione corretamente, é necessário que não haja nenhuma instância do Chrome, em primeiro ou segundo plano, ativa.
|
||||
|
||||
---
|
||||
#### Parâmetros:
|
||||
- to: Tempo em segundos que a API esperará pela abertura do Chrome. Caso o tempo seja excedido sem que o Chrome seja aberto com sucesso, é retornado um erro.
|
||||
---
|
||||
#### Retorna:
|
||||
|
||||
"" -> String vazia
|
||||
"""
|
||||
return self.__request_get__(f"/ipc/chrome/start?to={to}")
|
||||
|
||||
def start_headless (self):
|
||||
"""
|
||||
## Chrome Start Headless
|
||||
Inicia uma nova sessão/instância do Google Chrome em segundo plano na máquina.
|
||||
|
||||
---
|
||||
#### IMPORTANTE:
|
||||
É um erro comum já estar com o Google Chrome aberto para realizar outras tarefas enquanto programa. Porém, para que este método funcione corretamente, é necessário que não haja nenhuma instância do Chrome, em primeiro ou segundo plano, ativa.
|
||||
|
||||
---
|
||||
#### Parâmetros:
|
||||
---
|
||||
|
||||
---
|
||||
#### Retorna:
|
||||
|
||||
"" -> String vazia
|
||||
"""
|
||||
return self.__request_get__("/ipc/chrome/startHeadless")
|
||||
|
||||
def stop (self):
|
||||
"""
|
||||
## Chrome Stop
|
||||
Finaliza todas as sessões/instâncias ativas, em primeiro ou segundo plano, da máquina. Caso não haja nenhuma sessão ativa, não faz nada.
|
||||
|
||||
---
|
||||
#### IMPORTANTE:
|
||||
Este método funciona apenas com instâncias inicializadas pelo Client do Chrome. Caso uma sessão do Chrome tenha sido iniciada por outros modos, não surtirá efeito.
|
||||
|
||||
---
|
||||
#### Parâmetros:
|
||||
---
|
||||
|
||||
---
|
||||
#### Retorna:
|
||||
|
||||
"" -> String vazia
|
||||
"""
|
||||
return self.__request_get__("/ipc/chrome/stop")
|
||||
|
||||
def new (self, url: str):
|
||||
"""
|
||||
## Chrome New
|
||||
Abre uma nova aba na instância do Google Chrome inicializada pelo client.
|
||||
|
||||
---
|
||||
#### Parâmetros:
|
||||
- url: Endereço web do site que se deseja acessar na nova aba.
|
||||
|
||||
---
|
||||
#### Retorna:
|
||||
|
||||
-> ID da aba aberta.
|
||||
"""
|
||||
|
||||
url = urllib.parse.quote(url, "")
|
||||
return self.__request_get__(f"/ipc/chrome/new?url={url}")
|
||||
|
||||
def close (self, id: str):
|
||||
"""
|
||||
## Chrome Close
|
||||
Fecha a aba cujo ID foi informado como parâmetro.
|
||||
|
||||
---
|
||||
#### Parâmetros:
|
||||
- id: Identificador da aba que se deseja fechar.
|
||||
|
||||
---
|
||||
#### Retorna:
|
||||
|
||||
"" -> String vazia
|
||||
"""
|
||||
|
||||
return self.__request_get__("/ipc/chrome/close/"+id)
|
||||
|
||||
def eval (self, id: str, command: str) -> dict:
|
||||
"""
|
||||
## Chrome Eval
|
||||
Digita o comando recebido no Console JavaScript da página cujo ID foi recebido.
|
||||
|
||||
---
|
||||
#### Parâmetros:
|
||||
- id: Identificador da aba em que se quer acessar o console.
|
||||
- command: Comando DOM JavaScript
|
||||
---
|
||||
#### Retorna:
|
||||
-> ?
|
||||
"""
|
||||
|
||||
raw_return = self.__request_raw_post__("/ipc/chrome/eval/"+id, command)
|
||||
|
||||
return raw_return['result']['result']['value'] if ('value' in raw_return['result']['result']) else None
|
||||
|
||||
def wait (self, id: str, condition: str, to: int):
|
||||
"""
|
||||
## Chrome Wait
|
||||
Espera por uma determinada quantidade de tempo até que a condição passada como parâmetro seja verdadeira.
|
||||
|
||||
---
|
||||
#### Parâmetros:
|
||||
- id: Identificador da aba em que se quer utilizar o método.
|
||||
- condition: Condição que se quer verificar. É bastante comum utilizar este método para aguardar que elementos da página web carreguem, para isso, utilize o formato: comando_para_o_elemento != undefined.
|
||||
- to: Tempo limite de espera pelo valor de verdade da condição.
|
||||
|
||||
---
|
||||
#### Retorna:
|
||||
- Sucesso: "ok".
|
||||
- Falha: Mensagem de erro.
|
||||
"""
|
||||
|
||||
return self.__request_raw_post__(f"/ipc/chrome/wait/{id}?to={to}", condition)
|
||||
|
||||
def send(self, id: str, method: str, parameters: dict = {}):
|
||||
"""
|
||||
## Chrome Send
|
||||
Este método realiza a manipulação da página cujo id for informado através de domínios do Chrome Dev Tools Protocol. Para mais informações sobre como utilizar esta ferramenta, visite o site:
|
||||
|
||||
https://chromedevtools.github.io/devtools-protocol/
|
||||
|
||||
---
|
||||
#### Parâmetros:
|
||||
- id: Identificador da página web em que se quer realizar a manipulação.
|
||||
- method: Nome do método DTP que se quer aplicar.
|
||||
- parameters: Parâmetros requeridos pelo método informado no parâmetro anterior. Caso o método não exija parâmetros, não envie nada.
|
||||
|
||||
---
|
||||
#### Retorna:
|
||||
-> O retorno desta função não é previsivel, ele varia de acordo com qual método DVP foi utilizado e o respectivo retorno dele.
|
||||
"""
|
||||
|
||||
object = {"method": method, "params": parameters}
|
||||
return self.__request_json_post__("/ipc/chrome/send/"+id, object)
|
||||
|
||||
def open_tabs (self) -> List[dict]:
|
||||
"""
|
||||
## Chrome Open Tabs
|
||||
Este método busca todas as abas abertas no navegador Chrome e retorna dados sobre elas.
|
||||
|
||||
---
|
||||
#### Parâmetros:
|
||||
---
|
||||
|
||||
---
|
||||
#### Retorna:
|
||||
-> Lista de dicionários com o nome das abas e outras informações sobre as mesmas.
|
||||
"""
|
||||
|
||||
return self.__request_json_get__("/ipc/chrome/opentabs")
|
||||
|
||||
# # ====================================== BROKEN ======================================
|
||||
# def find_tab_by_url (self, url: str = "https://www.google.com/"):
|
||||
# """
|
||||
# ## Chrome Find Tab By Url
|
||||
# Este método procura a url recebida entre as abas abertas no Google Chrome.
|
||||
|
||||
# ---
|
||||
# #### Parâmetros:
|
||||
# - url: Link que se deseja buscar entre as abas abertas.
|
||||
|
||||
# ---
|
||||
# #### Retorna:
|
||||
# -> ID da aba encontrada com a url correspondente.
|
||||
# """
|
||||
|
||||
# url = urllib.parse.quote(url, "")
|
||||
# return self.__request_get__("/ipc/chrome/findtabbyurl/"+url)
|
||||
|
||||
def find_tab_by_title (self, title: str):
|
||||
"""
|
||||
## Chrome Find Tab By Title
|
||||
Este método procura entre as abas abertas no Google Chrome, uma que possua o título correspondente ao que foi dado.
|
||||
|
||||
---
|
||||
#### Parâmetros:
|
||||
- title: Título da aba que se deseja procurar.
|
||||
|
||||
---
|
||||
#### Retorna:
|
||||
-> ID da aba encontrada com o título correspondente.
|
||||
"""
|
||||
|
||||
title = urllib.parse.quote (title, "")
|
||||
return self.__request_get__("/ipc/chrome/findtabbytitle/"+title)
|
Loading…
Reference in New Issue