New to automation, I have a couple of months under my belt and learning when I have free time.
I'm trying to confirm that a user name appears inside a table and the name will appear on several rows.
I'm using something like this:
#step('Users homepage my lists created by is only user "{username}"')
def step_impl(context, username):
users_name = context.browser.find_elements_by_xpath(
"//*[#id='apollo-table_wrapper']][contains(text(),'%s')]" % username)
I know the xpath is correct for the table but if I want to verify that only a specific username is visible on the screen I'm running into an issue.
In this image below I want to have a test that makes sure only the user of "mike" is present on the page. I will call out "mike" in the feature file...
General idea of the UI
You have a typo change ] to //:
users_name = context.browser.find_elements_by_xpath(
"//*[#id='apollo-table_wrapper']//[contains(text(),'%s')]" % username)
To loop through you can do something like this:
users_names = context.browser.find_elements_by_xpath("//*[#id='apollo-table_wrapper']")
print([i.text for i in users_names if i.text == "Mike"])
# Or you can append to list:
res = []
[res.append(i.text) for i in users_names if i.text == "Mike"]
print(res)
If i understood you, you wan't to verify all the names in the grid, and detect if any of these names isn't "Mike". You can use the code below to select all the names from the grid, and then verify if any of them is different from the expected
#This will only work if the Xpath bellow selects only the names, if it
#selects other fields from the table it will verify if all the fields are
#"Mike", instead of only the Name fields.
users_name = context.browser.find_elements_by_xpath("//*[#id='apollo-table_wrapper']")
result = true
expectedValue = "Mike"
for x in users_name:
if x.text != expectedValue
result = false
break
#Assert result here
Let me know if this doesn't work.
Related
Sorry for the noob question.
I've defined a button in PySimpleGUI that should check the number of records in the API and return in a text field in the window, that number, within a text string.
I'm doing something wrong with the hierarchy of statements, I think.
When I add indentation to the last two lines quoted, then nothing happens upon button click, but if I reduce indents, an error says that 'response' is undefined.
Passing the function result into the string directly doesn't seem to work either (error says you can't do it).
I think I've tried every combination of indents and also parameters given to the get_entries function.
if event == '-CHECK-':
baseurl_short = 'https://api.nfz.gov.pl/app-umw-api/agreements?page=1&limit=25&format=json&api-version=1.2&sort=provider-code:ASC'
if method == ['Service Type']:
api_url_short = ''.join([baseurl_short, '&serviceType=', type_input, '&year=', year_input, '&branch=', region_input])
else:
api_url_short = ''.join([baseurl_short, '&productCode=', code_input, '&year=', year_input, '&branch=', region_input])
def main_request_short(api_url):
r = requests.get(api_url)
return r.json()
def get_entries(response):
return math.ceil(response['meta']['count'])
sum_entries = get_entries(response)
window['-OUTPUT-'].update('Downloading ' + sum_entries + ' records')
im trying to use pyviz in a jupyter notebook to create some sort of form for others to populate with data.
this data then is to be saved to a nested list on the click of the save button. then you repeat it for every person.
then i need a button to show the current input of the nested list.
can someone point me in the right direction?so far ive got only the input fields, the list is always empty.
# companies at which people are working
company = ['wal', 'even', 'foot']
class Company(param.Parameterized):
# dropdown of company
company = param.ObjectSelector(objects=company)
# name of person
personname = param.String(doc="name")
# age of person
age = param.Number(0)
# save to list button
save_btn = param.Action(lambda self:self.param.trigger('save_btn'),doc="""Save""")
# show list
show_btn = param.Action(lambda self: self.param.trigger('show_btn'),doc="""Show dicitonary""")
# dict which collects all input
all_persons = []
# return content of dict
#param.depends('show_btn')
def show_list(self):
return self.all_persons
# save form content to dict
#param.depends('save_btn')
def save_to_list(self):
temp_list = []
temp_list.append[self.company]
temp_list.append[self.personname]
temp_list.append[self.age]
run = Company()
pn.Column(run.param.company, run.param.personname, run.param.age,run.param.save_btn,run.param.show_btn, run.show_list)
# desired nested list
# [['wal', "bob", "34"], ["foot", "anna", "56"]]
Your code contains a few typos and loose ends. From top to bottom:
all_persons is defined as empty list, but never connected to the temp list created in the method save_to_list()
#param.depends(...) is missing watch=True, e.g. #param.depends('show_btn', watch=True)
show_list() returns self.all_persons, but this variable is never used anywhere
E.g.:
company = ['A', 'B'] # simplified code
class Company(param.Parameterized):
company = param.ObjectSelector(default=company[0], objects=company)
person_name = param.String(doc="name")
age = param.Number(0)
save_btn = param.Action(lambda self: self.save_to_list() , doc="""Save""") # no need for param.trigger here...
print_btn = param.Action(lambda self: self.print_list() , doc="""Print""") # no need for param.trigger here...
all_persons = [] # starts with an empty list
# no need for param.depends, as the method directly is called via param.Action,
def save_to_list(self):
print('safe to list: {}, {}, {}'.format(self.company, self.person_name, self.age))
temp_list = []
temp_list.append(self.company) # use () for append, not []
temp_list.append(self.person_name)
temp_list.append(self.age)
print('temp_list: {}'.format(temp_list))
self.all_persons.append(temp_list)
# no need for param.depends, as the method is directly called via param.Action,
def print_list(self):
print('all_persons: {}'.format(self.all_persons))
run = Company()
layout = pn.Row(run.param)
layout.app() # to see print statements in a notebook, use the server variant via 'app()'
I have a function executing in a api.onchange('bom_line_ids'), inside this function I want to have a if statement to clear bom_line_ids if a condition is matched. I used self.bom_line_ids.product_id = False
but for some reason the field is cleared (saw this in the prints, but it's not updated in the view).
#api.onchange('bom_line_ids')
def get_excl_list(self):
list1 = []
for i in self.excl_list:
list1.append(i.id)
list2 = []
for j in self.bom_line_ids:
list2.append(j.product_id.id)
if j.product_id.id in list1:
warning_message = "Product: " + self.env['product.template'].search([('id','=',j.product_id.id)]).name + " can't be added to the BoM.\n Please select another product."
print "self.bom_line_ids.product_id", self.bom_line_ids.product_id
self.bom_line_ids.product_id = False
print "self.bom_line_ids.product_id", self.bom_line_ids.product_id
return { 'warning': {'title': 'Product error', 'message':warning_message} }
There is an issue in Odoo talking about this. Someone already made a pull request.
You can check as well this other question to solve the issue manually: One2many field on_change function can't change its own value?
Maybe you have to select on which record on bom_line_ids you want to remove the product, because self.bom_line_ids is a one2many.
Replace
self.bom_line_ids.product_id = False
by
j.product_id = False
or
self.bom_line_ids[self.bom_line_ids.index(j)].product_id = False
Yes it happens. When You try to set value for a field through onchange method, the change doesnot appear on the view. However the field value does change. I fixed this issue by setting the 'compute in the field property and the function set here is the same as in the on_change'. So the value get updated in the view as well. For eg ->
job_titles = fields.Char('Job',compute='myemply_name',store=True)
#api.onchange('new_empl')
#api.depends('new_empl')
def myemply_name(self):
self.job_titles = value
Okay there is a QListView with a standard model.
How to iterate over ALL the items in the list (or get them all at once), and transform their content into Python's list of strings?
There are tons of receipts for PyQT4, and hours of googling gave me nothing for PyQT5. That's just terrible! I'm really upset we chose version 5, but that wasn't my choice =(
(somewhere in the UI)
self.listView = QtWidgets.QListView(self.centralwidget)
(somewhere in the View code)
def users_to_list_view(users, list_view):
list_model = QStandardItemModel(list_view)
for user in users:
item = QStandardItem(user.username)
list_model.appendRow(item)
list_view.setModel(list_model)
def someSignal():
...
users_to_list_view(users, self.ui.listView)
def onSave():
...
AND HERE I WANT TO GET ALL THE ITEMS FROM THAT BLOODY LIST!
Should be something like
def users_to_list_view(users, list_view):
self.list_model = QStandardItemModel(list_view)
for user in users:
item = QStandardItem(user.username)
self.list_model.appendRow(item)
list_view.setModel(list_model)
def onSave():
self.list_model. # get items with some method
I am having problems understanding how to work with query results. I asked about half a dozen questions about this but I still do not understand. I copy from previous code and I make it work somehow but since I don't understand the underlying concept the code breaks down if I make a minor change. I would really appreciate if you could tell me how you visualize what is happenning here and explain it to me. Thank you.
class ReceiveEmail(InboundMailHandler):
def receive(self, message):
logging.info("Received email from %s" % message.sender)
plaintext = message.bodies(content_type='text/plain')
for text in plaintext:
txtmsg = ""
txtmsg = text[1].decode()
logging.info("Body is %s" % txtmsg)
logging.info("CC email is %s" % ((message.cc).split(",")[1]))
query = User.all()
query.filter("userEmail =", ((message.cc).split(",")[1]))
results = query.fetch(1)
for result in results:
result.userScore += 1
um = results[0]
um.userScore = result.userScore
um.put()
In this code, as I understand it, the query takes the second email address from the cc list and fetches the result.
Then I increment the userScore by 1.
Next, I want to update this item in Datastore so I say
um = results[0]
um.userScore = result.userScore
um.put()
But this gives an index out of range error:
um = results[0]
IndexError: list index out of range
Why? I am imagining that results[0] is the zeroeth item of the results. Why is it out of range? Only thing I can think of is that, the list may be None. But I don't understand why. It must have the 1 item that was fetched.
Also, if I try to test for the first email address by changing the index from [1] to [0]
query.filter("userEmail =", ((message.cc).split(",")[0]))
then I don't get the IndexError.
What am I doing wrong here?
Thanks!
EDIT
See comments:
(message.cc).split(",")[0])
left a space in front of the emails (starting with the second email), so the query was not matching them;
>>> cc.split(",")
['cc12#example.com', ' cc13#example.com', ' cc13#example.com']
adding a space after comma fixed the problem:
>>> listcc = cc.split(", ")
>>> listcc
['cc12#example.com', 'cc13#example.com', 'cc13#example.com']
>>>
To understand the code break it down and look at it piece by piece:
class ReceiveEmail(InboundMailHandler):
def receive(self, message):
logging.info("Received email from %s" % message.sender)
# Get a list of CC addresses. This is basically a for loop.
cc_addresses = [address.strip() for address in message.cc.split(",")]
# The CC list goes with the message, not the bodies.
logging.info("CC email is %s" % (cc_addresses))
# Get and iterate over all of the *plain-text* bodies in the email.
plaintext = message.bodies(content_type='text/plain')
for text in plaintext:
txtmsg = ""
txtmsg = text[1].decode()
logging.info("Body is %s" % txtmsg)
# Setup a query object.
query = User.all()
# Filter the user objects to get only the emails in the CC list.
query.filter("userEmail IN", cc_addresses)
# But, only get at most 10 users.
users = query.fetch(10)
logging.info('Got %d user entities from the datastore.' % len(users))
# Iterate over each of the users increasing their score by one.
for user in users:
user.userScore += 1
# Now, write the users back to the datastore.
db.put(users)
logging.info('Wrote %d user entities.' % len(users))
I would make an adjustment to your model structure. When you create the User entity, I would set the key_name to the email address. You will be able to make your queries much more efficient.
Some references:
List Comprehension.
Query Object.
db.put().