Somebody can give a help...
I am just starting to learn more about PageObjects and Python and I am facing the following problem:
[Card(name ="Dormir", description = "Dormir é muito bom")]
Traceback (most recent call last):
File "C:\python_pageObjects\main.py", line 76, in <module>
todos[0].do()
TypeError: 'tuple' object is not callable
My code so far…
#PageElement
from abc import ABC
class PageElement(ABC):
def __init__(self, webdriver, url=''):
self.webdriver = webdriver
self.url = url
def find_element(self, locator):
return self.webdriver.find_element(*locator)
def find_elements(self, locator):
return self.webdriver.find_elements(*locator)
def open(self):
self.webdriver.get(self.url)
------------------------------------------------
# Locator
from selenium.webdriver.common.by import By
class Locator():
NAME = (By.ID, "todo-name")
DESCRIPTION = (By.ID, "todo-desc")
URGENT = (By.ID, "todo-next")
SUBMIT = (By.ID, "todo-submit")
#AFazer
FIELDSET = (By.CSS_SELECTOR, "div.body_a fieldset")
CARD = (By.CLASS_NAME, "terminal-card")
#Card
CARD_NAME = (By.CSS_SELECTOR, "header.name")
CARD_DESCRIPTION = (By.CSS_SELECTOR, "div.description")
CARD_DO_BUTTON = (By.CSS_SELECTOR, "button.do")
CARD_CANCEL_BUTTON = (By.CSS_SELECTOR, "button.cancel")
-------------------------------------------------------------
from element import PageElement
from locator import Locator
class Todo(PageElement):
name = Locator.NAME
description = Locator.DESCRIPTION
urgent = Locator.URGENT
submit = Locator.SUBMIT
def create_todo(self, name, description, urgent=False):
self.webdriver.find_element(*self.name).send_keys(name)
self.webdriver.find_element(*self.description).send_keys(description)
if urgent:
self.webdriver.find_element(*self.urgent).click()
self.webdriver.find_element(*self.submit).click()
--------------------------------------------------------------
class AFazer(PageElement):
fieldset = Locator.FIELDSET
card = Locator.CARD
def todos(self):
cards = self.find_elements(self.card)
# return [Card(card) for card in cards] #Pythinic
po_cards = []
for card in cards:
po_cards.append(Card(card))
return po_cards
------------------------------------------------------
class Card:
def __init__(self,selenium_object):
self.selenium_object = selenium_object
self.name = Locator.CARD_NAME
self.description = Locator.CARD_DESCRIPTION
self.do = Locator.CARD_DO_BUTTON
self.cancel = Locator.CARD_CANCEL_BUTTON
self._load()
def do(self):
self.selenium_object.find_element(*self.do).click()
def cancel(self):
self.selenium_object.find_element(*self.cancel).click()
def _load(self):
self.name = self.selenium_object.find_element(*self.name).text
self.description = self.selenium_object.find_element(*self.description).text
def __repr__(self):
return f'Card(name ="{self.name}", description = "{self.description}")'
-----------------------------------------------------------------------
# Execution
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
driver = webdriver.Chrome(ChromeDriverManager().install())
url = 'https://selenium.dunossauro.live/todo_list.html'
todo_element = Todo(driver,url)
todo_element.open()
todo_element.create_todo(
'Dormir',
'Dormir é muito bom'
)
a_fazer = AFazer(driver,url)
todos = a_fazer.todos()
print(a_fazer.todos())
# takes the first card from the list of Card and clicks Do.
todos[0].do()
todos[0].cancel()
I am trying to figure out the error, but I don't understand why I am getting this error. Because the return of todos[0] should be a Card object that contains two properties (name and description), so if anyone can give me a hand with this, thank you very much.
CodePudding user response:
@Bruno Lorena, it seems since you have an instance variable name do
, and a method name do()
in the same class. And when you refer todo[0].do()
, it is taking your instance variable do
and not your method do()
. So I suggest you change the name for one of them.