getElementById() takes exactly 1 argument (2 given) - python

I want to do an automation of the Internet Explorer. Open the Internet Explorer, navigate to login.live.com and set a value into the email textbox.
Here's the simple script:
import win32com.client
import time
IE = win32com.client.DispatchEx("InternetExplorer.Application")
IE.Visible = 1
IE.Navigate('login.live.com')
time.sleep(5)
DOC = IE.document
DOC.getElementById('i0116').value = 'test'
The last line always returns the following TypeError:
getElementById() takes exactly 1 argument (2 given)
When I try to add the value through the console of the Internet Explorer it works.
Btw. the getElementsByTagName() method works without any Errors.
Thanks for any help!

Okay.. I wrote a workaround for this:
DOC = IE.Document
inputs = DOC.documentElement.getElementsByTagName('input')
for field in inputs:
if field.id == 'i0116':
email = field
break
email.value = 'example#test.com'
For browser automation I recommend to use the Selenium library.

As this answer suggests you have to use
DOC.Body.getElementById('i0116').value = 'test'

Related

Pytest bdd error "scenario_wrapper() missing 1 required positional argument: 'request'"

I'm learning pytest and I get an error trying to run a test that worked fine before I added pytest-bdd(feature file, step file is the one I'm trying to run)
This is my code:
import pytest
import time
from selenium import webdriver
from pytest_bdd import scenario, given, when, then
#scenario('../feature/learn.feature', 'learning pytest-bdd')
#when('Does work-->website open, find element')
def does_work():
driver = webdriver.Edge(r"C:/Users/artri/Downloads/edgedriver_win64/msedgedriver.exe")
driver.get('https://www.example.com/')
driver.maximize_window()
print(driver.title)
time.sleep(5)
element = driver.find_element_by_xpath("//button[#class='btn btn-outline-light btn-lg btn-close']")
element.click()
name = driver.find_element_by_xpath("//a[#href='/items/something/']").text
driver.quit()
return name
#then('Get text "something"')
def test_work():
assert does_work() == 'something'
It finds the element and checks if it's value is right. I would like to know why after adding steps and making the feature file it doesn't work. Other test in the same steps file works just like they did before.
The error massage:
#then('Get text "something"')
def test_work():
> assert does_work() == 'something'
E TypeError: scenario_wrapper() missing 1 required positional argument: 'request'
I looked at a couple similar questions, but non were understandable for me.
If anyone has any idea where the issue might be or some links would be very appreciated!
You have decorator without function def.
From documentation at: https://github.com/pytest-dev/pytest-bdd
#scenario('publish_article.feature', 'Publishing the article')
def test_publish():
pass
You need to decorate empty function.

Selenium webdriver isn't able to clear a field, but is able to send_keys to it

I'm trying to create a program that signs up for instagram with a new account, I've got the emails and the rest generated, when I go ahead and send_keys to the appropriate fields, it does it just fine. I wanted to implement a retry function, which would clear the email field and try with a different mail. However this does not work, even though send_keys to it worked previously? Snippet of my code below.
driver.get('https://www.instagram.com')
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").send_keys(mail)
driver.find_element_by_xpath("//*[contains(#aria-label,'Full')]").send_keys(name + lastname)
driver.find_element_by_xpath("//*[contains(#aria-label,'User')]").send_keys(namae+lastonamae+pamae2)
driver.find_element_by_xpath("//*[contains(#aria-label,'Password')]").send_keys(password)
driver.find_element_by_xpath("//*[contains(#type,'submit')]").click()
This attempts to create a new account with the appropriate credentials, however when it fails, I want it to try to look for an element that is only present when it fails, and if it finds that, it should clear the email field and retry with a different one. Code below.
driver.find_element_by_xpath('//*[#id="react-root"]/section/main/article/div[2]/div[1]/div/form/div[3]/div/div[2]/span') #this looks for the element only present on the fail page
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").clear()
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").send_keys(mail2)
It doesn't clear the field, but doesn't raise an error either. It then proceeds to type the 2nd email with no problems. I appreciate any help on the matter.
EDIT: Posting a bigger chunk of the code.
def signup():
driver.get('https://www.instagram.com')
time.sleep(7)
if trycounter < 3: #this is almost always true, just a failsafe
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").send_keys(mail1)
driver.find_element_by_xpath("//*[contains(#aria-label,'Full')]").send_keys(name + ' ' + lastname)
driver.find_element_by_xpath("//*[contains(#aria-label,'User')]").send_keys(name+lastname+extension)
driver.find_element_by_xpath("//*[contains(#aria-label,'Password')]").send_keys(password)
driver.find_element_by_xpath("//*[contains(#type,'submit')]").click()
time.sleep(7)
try: #this only executes if a popup that wants you to confirm your age pops up
driver.find_element_by_xpath('//*[#id="igCoreRadioButtonageRadioabove_18"]').click()
driver.find_element_by_xpath('/html/body/div[3]/div/div[3]/div/button').click()
time.sleep(5)
except:
pass
try:
randomgen() #generates the mail,password and name
driver.find_element_by_xpath('//*[#id="react-root"]/section/main/article/div[2]/div[1]/div/form/div[3]/div/div[2]/span')
time.sleep(1)
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").clear()
time.sleep(1)
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").send_keys(mail2)
driver.find_element_by_xpath("//*[contains(#aria-label,'User')]").send_keys(username)
driver.find_element_by_xpath("//*[contains(#type,'submit')]").click()
time.sleep(7)
You can use following code as alternative for clear method:
from selenium.webdriver.common.keys import Keys
email_element = driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]")
email_element.send_keys(Keys.CONTROL, 'a')
email_element.send_keys(mail1)
fullname_element = driver.find_element_by_xpath("//*[contains(#aria-label,'Full')]")
fullname_element.send_keys(Keys.CONTROL, 'a')
fullname_element.send_keys(name + ' ' + lastname)
# do it for other field as well
So this will definitely work as a workaround. I just tried it on instagram. Although there was no field with an aria label called Email for me. It was aria-label "Mobile Number or Email" for me.
driver.execute_script("$(\"input[aria-label='Email']"\").value = '';");
I will keep looking at it to see why the clear command didn't work though.
You can try something like this to delete mail1.
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").send_keys(Keys.chord(Keys.CONTROL,"a"))
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").send_keys(Keys.DELETE)
driver.find_element_by_xpath("//*[contains(#aria-label,'Email')]").send_keys(mail2)

Problem using Yandex translater API in Python

I've been asked to translate some words, and I'm using Python to do it. Yandex has an API that is supposed to be used withing Python, documentation here :
https://pypi.org/project/yandex-translater/1.0/
I followed the steps, but Always get the same error that seems to be withing the API, or maybe I'm not setting Something right in my code.
The code goes as follow :
from yandex import Translater
tr = Translater()
tr.set_key('my API key not given here')
tr.set_text("Hello World")
tr.set_from_lang('en')
tr.set_to_lang('fr')
result = tr.translate()
print(result)
I then get this error :
File "C:\Users\BMQT\Desktop\Scraping\test.py", line 2, in <module>
tr = Translater()
File "C:\Program Files\Python37\lib\site-packages\yandex\Translater.py", line 23, in __init__
self.default_ui = locale.getlocale()[0].split('_')[0]
AttributeError: 'NoneType' object has no attribute 'split'
A quick look if you need in the translater.py goes as follow for line 23 :
self.default_ui = locale.getlocale()[0].split('_')[0]
Is the API broken or am I wrong in my code? Thanks for the answers!
I've used another api module called yandex_translate, and it works fine.
from yandex_translate import YandexTranslate
translate = YandexTranslate('mykey')
traduction =('Translate:', translate.translate('bonjour', 'fr-ar'))
print(traduction)
Don't know what was wrong with the previous one, maybe outdated.
translater object need to be created like this: tr = Translater.Translater()
from yandex import Translater
tr = Translater.Translater()
tr.set_key('my API key not given here')
tr.set_text("Hello World")
tr.set_from_lang('en')
tr.set_to_lang('fr')
result = tr.translate()
print(result)

Selenium, how to start Firefox with addons?

I want to load the Firefox Addon RequestPolicy. This is how i tried it:
rp = open(wd + "/requestpolicy.xpi")
firefoxProfile = FirefoxProfile()
firefoxProfile.add_extension(rp)
self.driver = webdriver.Firefox(firefoxProfile)
self.usr = user.User(self.driver, username, password, world)
self.usr.login()
No error, according to the Docs it should work, but it doesn't, it still starts without the addon.
Next thing i've tried is calling it this way:
self.driver = webdriver.Firefox(browser_profile=firefoxProfile)
Output:
TypeError: __init__() got an unexpected keyword argument 'browser_profile'
But this is an aspect of python i dont know much about. I got that idea because the source looks that way.
I don't have enough Stackoverflow rep to leave a comment on your question, and unfortunately I don't know the answer to your question, but for what it's worth you need to call webdriver.Firefox() with firefox_profile, not browser_profile, as you have done.
See also: http://code.google.com/p/selenium/source/browse/trunk/py/selenium/webdriver/firefox/webdriver.py#33
what I did and worked was:
profile=webdriver.FirefoxProfile()
profile.add_extension("/home/.../.mozilla/firefox/zrdb9ki8.default/extensions/{d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}.xpi") # for adblockplus
profile.set_preference("extensions.adblockplus.currentVersion", "2.8.2")
Fox = webdriver.Firefox(profile)
Fox.get(website_Url) #https://.....
It took me a few hours to find a solution.
All you need to do is download your extension as .xip file.
And then add this line to your code:
driver.install_addon('/Users/someuser/app/extension.xpi', temporary=True)
Replace "/Users/someuser/app/extension.xpi" with path to your extension .xip file.
Additionally you should not open the xpi file directly. Instead try to just give the address:
firefoxProfile.add_extension(wd + "/requestpolicy.xpi")

Why do I get TypeError: get() takes exactly 2 arguments (1 given)? Google App Engine

I have been trying and trying for several hours now and there must be an easy way to retreive the url. I thought this was the way:
#from data.models import Program
import basehandler
class ProgramViewHandler(basehandler.BaseHandler):
def get(self,slug):
# query = Program.all()
# query.filter('slug =', fslug)
self.render_template('../presentation/program.html',{})
Whenever this code gets executed I get this error on the stacktrace:
appengine\ext\webapp__init__.py", line 511, in call
handler.get(*groups)
TypeError: get() takes exactly 2 arguments (1 given)
I have done some debugging, but this kind of debugging exceeds my level of debugging. When I remove the slug from def get(self,slug) everything runs fine.
This is the basehandler:
import os
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
class BaseHandler(webapp.RequestHandler):
def __init__(self,**kw):
webapp.RequestHandler.__init__(BaseHandler, **kw)
def render_template(self, template_file, data=None, **kw):
path = os.path.join(os.path.dirname(__file__), template_file)
self.response.out.write(template.render(path, data))
If somebody could point me in the right direction it would be great! Thank you! It's the first time for me to use stackoverflow to post a question, normally I only read it to fix the problems I have.
You are getting this error because ProgramViewHandler.get() is being called without the slug parameter.
Most likely, you need to fix the URL mappings in your main.py file. Your URL mapping should probably look something like this:
application = webapp.WSGIApplication([(r'/(.*)', ProgramViewHandler)])
The parenthesis indicate a regular expression grouping. These matched groups are passed to your handler as arguments. So in the above example, everything in the URL following the initial "/" will be passed to ProgramViewHandler.get()'s slug parameter.
Learn more about URL mappings in webapp here.
If you do this:
obj = MyClass()
obj.foo(3)
The foo method on MyClass is called with two arguments:
def foo(self, number)
The object on which it is called is passed as the first parameter.
Maybe you are calling get() statically (i.e. doing ProgramViewHandler.get() instead of myViewHandlerVariable.get()), or you are missing a parameter.

Categories

Resources