How to get the class name inside a child window using pywinauto? - python-3.x

I am trying to automate an app using pywinauto. Here is a problem when I need to locate a specific window.
For example, I want to get the window 'AfxWnd4214', but I can only access to window "AfxWnd42".
| AfxWnd42 - '' (L1044, T410, R1060, B426)
| ['AfxWnd4214', 'V11.82AfxWnd4212']
| child_window(class_name="AfxWnd42")
| AfxWnd42 - '' (L1044, T410, R1060, B426)
| ['AfxWnd4212', 'V11.82AfxWnd4212']
| child_window(class_name="AfxWnd42")
I access it by this code. But it is not specific enough. The sequence of this window may change in the tree.
pywinauto.app.window(class_name = "AfxWnd42", found_index = 0)
When I try this code:
pywinauto.app.window(class_name = "AfxWnd4214", found_index = 0)
It says
pywinauto.findwindows.ElementNotFoundError: {'class_name': 'AfxWnd4214', 'found_index': 0, 'backend': 'win32', 'process': 15404}
Is there any better method to access this window?
Thank you.

There are various search criteria see below; Try using combination of these.
Once I used auto_id and it worked for me.
'''
Find elements based on criteria passed in
Possible values are:
* **class_name** Elements with this window class
* **class_name_re** Elements whose class matches this regular expression
* **parent** Elements that are children of this
* **process** Elements running in this process
* **title** Elements with this text
* **title_re** Elements whose text matches this regular expression
* **top_level_only** Top level elements only (default=True)
* **visible_only** Visible elements only (default=True)
* **enabled_only** Enabled elements only (default=False)
* **best_match** Elements with a title similar to this
* **handle** The handle of the element to return
* **ctrl_index** The index of the child element to return
* **found_index** The index of the filtered out child element to return
* **predicate_func** A user provided hook for a custom element validation
* **active_only** Active elements only (default=False)
* **control_id** Elements with this control id
* **control_type** Elements with this control type (string; for UIAutomation elements)
* **auto_id** Elements with this automation id (for UIAutomation elements)
* **framework_id** Elements with this framework id (for UIAutomation elements)
* **backend** Back-end name to use while searching (default=None means current active backend)
'''

Related

How do I autopopulate a tkinter table using a loop

I'm trying to auto-populate a tkinter table with the names of folders in a directory and details about their properties
grpdata_name = listdir(r"PATH")
grpdata_path = r"PATH\{}".format(grpdata_name[0])
grpdata_groupcount = -1
for x in grpdata_name :
grpdata_groupcount = grpdata_groupcount +1
grpdata_groupcurrent = 'grpdata_name{}{}{}'.format('[',grpdata_groupcount,']')
GUI_Table.insert(parent='',index='end',iid=0,text='',
values=('ID',grpdata_groupcurrent,'TIME CREATED','TIME MODIFIED','DEVICES'))
My current method is to change the selected element in a string. This creates a working cycle through each part of the string ( grpdata_name[0] , grpdata_name[1] etc)
I can't figure out how to use the contents of grpdata_groupcurrent as a variable, rather than a string.
This method isn't very efficient overall, so please let me know if there is a better way to do this.

how to use selenium python to open new chat whatsapp (i need to target the second icon New Chat)

I need to target the second icon New Chat but they have the same class name
from selenium import webdriver
driver = webdriver.Chrome('C:/Users/ka-my/AppData/Local/Programs/Python/Python37-32/chromedriver')
driver.get('https://web.whatsapp.com/')
input('Enter anything after scanning QR code')
user1 = driver.find_element_by_class_name('_3j8Pd')
user1.click()
1.i need to target the second icon New Chat
just like Facebook and google the class names are dynamically generated So the best way around that is to look for something constant which is the icon string
new_chat = driver.find_elements_by_xpath('//div[#title="New chat"]') # return a list
if new_chat:
new_chat[0].click()
To get 2nd icon in new chat, you can use this:
# get the 2nd element in the list
second_icon = driver.find_elements_by_xpath("//div[#class='_3j8Pd']")[1]
Or:
# get the 2nd element in the list
second_icon = driver.find_elements_by_xpath("//div[#class='_3j8Pd'][2]")
In first example, we are getting a list of all the div elements, and picking the 2nd item using the [1] index. In second example, we are using element index in XPath [2] to get the second element in the list. List index is 0-based and XPath element index is 1-based, so that is why we see 1 and 2 here.

ClickHouse- Search within nested fields

I have a nested field named items.productName wherein I want to check if the product name contains a particular string.
SELECT * FROM test WHERE hasAny(items.productName,['Samsung'])
This works only when the product name is Samsung.
I have tried array join
SELECT
*
FROM test
ARRAY JOIN items
WHERE items.productName LIKE '%Samsung%'
This works but it is very slow (~1 sec for 5 million records)
Is there a way to perform like within hasAny?
You can achieve this using arrayFilter function. ClickHouse docs
Query
Select * from test where arrayFilter(x -> x LIKE '%Samsung%', items.productName) != []
If you do not use != [] then you will get an error "DB::Exception: Illegal type Array(String) of column for filter. Must be UInt8 or Nullable(UInt8) or Const variants of them."

Extends Shopware Models

I need to extend Shopware variants models in order to add some custom attributes such as the type of metal,the type of stone a jewel, which is the base article.
These attributes will be used both in backend and frontend.
How can I do that? Thanks
Extending the Shopware core model itself is not possible at all. Depending on what specific model you are trying to extend there would be two different ways for some workaround:
If its the article itself that you want to extend you could use the custom attribute fields as described here: http://community.shopware.com/Anlegen,-Anpassen-und-Ausgabe-von-Artikel-Attributen_detail_1208.html
Another way would be to write a plugin where you create attribute fields by code on plugin install(). This is only possible on entities that do have an attribute table which belongs to the entity itself. For example s_order and s_order_attributes
For the second way create a method in your plugin's Bootstrap.php like the following and call the method in the plugin's install() method:
public function installOrderAttributes()
{
Shopware()->Models()->addAttribute(
's_order_attributes',
'ordermod',
'Random1',
'DECIMAL(12,4)',
false,
0.0000);
Shopware()->Models()->addAttribute(
's_order_attributes',
'ordermod',
'Random2',
'DECIMAL(12,4)',
false,
0.0000);
$metaDataCacheDoctrine = Shopware()->Models()->getConfiguration()->getMetadataCacheImpl();
$metaDataCacheDoctrine->deleteAll();
Shopware()->Models()->generateAttributeModels(array('s_order_attributes'));
}
The addAttribute() function in /engine/Shopware/Components/Model/ModelManager.php has the following signature:
/**
* Shopware helper function to extend an attribute table.
*
* #param string $table Full table name. Example: "s_user_attributes"
* #param string $prefix Column prefix. The prefix and column parameter will be the column name. Example: "swag".
* #param string $column The column name
* #param string $type Full type declaration. Example: "VARCHAR( 5 )" / "DECIMAL( 10, 2 )"
* #param bool $nullable Allow null property
* #param null $default Default value of the column
* #throws \InvalidArgumentException
*/
public function addAttribute($table, $prefix, $column, $type, $nullable = true, $default = null);
Hope this will help.
Kind regards!

How to use Objects.function if Objectsname is taken from String

I was wondering if this concept is doable:
Scenario:
4 areas on 1 stage which are quite similar (eg webcamconference, each area has the same functions)
Buttonobjects are numbered(eg area 1 has playbutton1,mutebutton1,namebutton1,namelabel1, etc)
every area gets a close-Button which closes/shuts down the area.(close1,close2,close3...)
i want to archive the following:
if(close1.isPressed){
function invisall(1);
}
/*
* instead of writing
* if(close1.isPressed){
* playbutton1._visible=false;
* mutebutton1._visible=false;
* }else if(close2.isPressed){
* playbutton2._visible=false;
* mutebutton2._visible=false;
* etc. resulting in an enormous block.
* the interesting part. buttonNr gets added via String to become a real buttonname(eg
* playbutton1 as mentioned above).*/
function invisall(int buttonNr){
String newPlayButtonObjectName="playbutton"+buttonNr;
newPlayButtonObjectName._visible=false;
String newMuteButton="mutebutton"+buttonNr;
newMuteButton._visible=false;
}
this should do the trick via dynamic Nr at the end of each default button(eg
playbutton)
but ofc
"playbutton1"._visible=false;
doesnt work because playbutton1 is still a String.
how can i take the String as a Buttonname/ButtonObject?
do i need to write an new function? this would destroy the purpose of less code.
maybe u like this idea. for now i will split the area into frames that i put on the stage. that should help.
cheers
function invisall(int buttonNr){
this["playbutton"+buttonNr]._visible=false;
this["mutebutton"+buttonNr]._visible=false;
}
I hope this is what you want.

Resources