Cannot run PhantomJS with Flask on Ubuntu VPS - python

I'm doing a testing unit that requires the tests to be run via web browser. I'm using Ubuntu VPS 14 with LAMP stack installed, mod_wsgi, selenium 2.44 and PhantomJS 1.9. I'm testing with the very simple code first:
from flask import Flask, request
from selenium import webdriver
app = Flask(__name__)
app.debug = True
#app.route("/test")
def test():
url = "http://www.google.com"
driver = webdriver.PhantomJS('./phantomjs')
driver.get(url)
result = driver.page_source
driver.close()
return result
if __name__ == "__main__":
app.run()
The code runs very smoothly on my local Ubuntu, it prints out the google page when I connect to: 127.0.0.1:5000/test . On my Ubuntu VPS, my have my flask already setup and running. Now i use the same code to be the index file (supposed all configs are OK and 'hello world' runs), I have 500 Internal Server Error when connecting to http://xxx.xxx.xxx.xxx/test
Apache log sends out the following error:
... service_args=service_args, log_path=service_log_path File
"/usr/local/lib/python2.7/ddist-packages/selenium/webdriver/phantomjs/service.py",
line 53, in init
self._log = open(log_path, 'w') in > ignored Exception AttributeError: "'Service' object
has no attribute '_log'" in > ignored
I changed the log_path for phatomJS but still have the same problem. However, if I open python console, doing line by line as following:
from selenium import webdriver
br = webdriver.PhantomJS('./phantomjs')
....
I got no error. It took me the whole day to fin the problem but I could't be able to fix it. Any ideas how to solve this problem?

Figure out the problem, current phantomjs and init.py don't have enough permission to manipulate the service.py of ghostdriver. Here is the fix:
Add a new user: "add username", then set "add username sudo"
Login to the new user, make sure every command you run from now on starts with "sudo"
In your flask application where init.py resides, create "ghostdriver.log" and "phantomjs" which is an executable file.
Chmod both of them to 777 : init.py, ghostdriver.log and phantomjs
Set the custom config in init.py for phantomjs:
br = webdriver.PhantomJS(service_log_path='./ghostdriver.log', executable_path='./phantomjs')
That's it, now your selenium + flask + phantomjs is now working correctly.

Related

Frozen-Flask errors while running cProfile

Building my static site (which uses Flask-Frozen to freeze a Flask app) works fine, but when I tried to profile it with python -m cProfile athena.py, I get the error
PermissionError: [Errno 13] Permission denied:
'/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/build
ie Frozen-Flask is trying to create its build folder in python's home folder on my system, not my current working directory. (Even though I am using a venv! which python yields /path/to/dir/bin/python.)
I was able to circumvent this by instantiating my Flask app with a hardcoded root path:
athena = Flask(__name__, root_path='/path/to/dir')
But then I get this error:
MissingURLGeneratorWarning: Nothing frozen for endpoints page,
hardpagelink. Did you forget a URL generator?
Trying to narrow down the issue with a debugger, I see that pages yields an empty list while profiling, and a list of pages in regular mode, which makes me suspect that the index is not being generated, or is generated somewhere else.
In addition there are some differences in my config (which is just generated from __name__):
Profiling config: 'DEBUG': False, 'FLATPAGES_AUTO_RELOAD': 'if debug',
'FLATPAGES_EXTENSION': '.html'
Regular config: 'DEBUG': True,
'FLATPAGES_AUTO_RELOAD': True, 'FLATPAGES_EXTENSION': '.md',
'FREEZER_BASE_URL': 'http://localhost/', 'FREEZER_REMOVE_EXTRA_FILES':
False
Here is the gist of my code (full code is here):
from flask import Flask, render_template
from flask_flatpages import FlatPages
from flask_frozen import Freezer
from flask_static_compress import FlaskStaticCompress
DEBUG = True
FLATPAGES_AUTO_RELOAD = DEBUG
FLATPAGES_EXTENSION = ".md"
FREEZER_REMOVE_EXTRA_FILES = False
FREEZER_BASE_URL = "http://localhost/"
athena = Flask(__name__)
athena.config.from_object(__name__)
pages = FlatPages(athena)
freezer = Freezer(athena)
#athena.route("/")
def index():
posts = [page for page in pages if "ispage" not in page.meta]
hpages = [page for page in pages if "ispage" in page.meta]
return render_template(
"index.html", pages=posts, hpages=hpages)
#athena.route("/<path:path>/")
def hardpagelink(path):
hpage = ""
for page in pages:
if page.path == path:
if page.meta["ispage"]:
hpage = page
hpages = [page for page in pages if "ispage" in page.meta]
return render_template("hard.html", page=hpage, hpages=hpages)
#athena.route("/posts/<path:path>/")
def page(path):
page = pages.get_or_404(path)
hpages = [page for page in pages if "ispage" in page.meta]
return render_template("page.html", page=page, hpages=hpages)
if __name__ == "__main__":
freezer.freeze()
If anyone wants to reproduce this here are instructions for setting up an env:
git clone https://github.com/lordgrenville/athena.git
cd athena/
brew install jez/formulae/pandoc-sidenote
# or cabal install pandoc-sidenote
npm install -g less
python3 -m venv blogenv/ && source blogenv/bin/activate
pip install werkzeug pypandoc virtualenv flask-flatpages frozen-flask pandoc-crossref flask-static-compress feedgen
python athena.py build
python -m cProfile athena.py build # fails

Unable to run PyTest-bdd step definition file as it throws index out of range error

Feature file is as below
Feature: Nopcommerce Login
Scenario: login to nopcommerce website
Given nopcommerce page is displayed
When user enters username as admin#yourstore.com
When user enters password as admin
Then user is able to login to nocpmmerce website
step definition python file is as below
from pytest_bdd import scenarios, given, when, then
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import pytest
scenarios('../features/NopcommerceLogin.feature')
#pytest.fixture()
def browser():
driver = webdriver.Safari()
yield driver
driver.quit()
#given("nopcommerce page is displayed")
def webpage(browser):
browser.get("http://admin-demo.nopcommerce.com")
#when("user enters username as admin#yourstore.com")
def enter_uname(browser):
browser.find_element_by_id("Email").send_keys("admin#yourstore.com")
#when("user enters password as admin")
def enter_pwd(browser):
browser.find_element_by_id("Password").send_keys("admin")
browser.find_element_by_xpath("/html/body/div[6]/div/div/div/div/div[2]/div[1]/div/form/div[3]/input").click()
#then("user is able to login to nocpmmerce website")
def loginsuccess(browser):
assert browser.current_url == "https://admin-demo.nopcommerce.com/admin/"
when the step_def file is run, the following error message is displayed
Traceback (most recent call last):
File "~/tests/step_defs/test_NopcommerceLogin.py", line 6, in
scenarios('../features/NopcommerceLogin.feature')
File "~/venv/lib/python3.8/site-packages/pytest_bdd/scenario.py", line 343, in scenarios
features_base_dir = get_features_base_dir(module)
File "~/venv/lib/python3.8/site-packages/pytest_bdd/scenario.py", line 295, in get_features_base_dir
return get_from_ini('bdd_features_base_dir', default_base_dir)
File "~/venv/lib/python3.8/site-packages/pytest_bdd/scenario.py", line 303, in get_from_ini
config = CONFIG_STACK[-1]
IndexError: list index out of range
It's not entirely the solution, and I have the same issue in PycharmIDE, but I suggest using terminal and start tests like:
pytest <test_fily.py>
for IDEA solution, still working on it
Change your configurations to use pytest configuration: screenshot
or try running using terminal : pipenv run python -m pytest
I guess the problem is that the pytest is not identifying any executable pytest method's in your step definition file. Please try changing the "scenarios" to "scenario" and add a pytest identifiable method below the same
#scenario('../features/NopcommerceLogin.feature')
def test_login():
pass
This approach always works for me and is based on Pytest-BDD doc.
Make sure that pytest configured in pycham
Enable Pytest for your project
Open the Settings/Preferences | Tools | Python Integrated Tools settings dialog as described in Choosing Your Testing Framework.
In the Default test runner field select pytest.
Click OK to save the settings
#Vova
I found that in the run configuration, the Working directory was incorrectly set to the directory where the steps python file was, instead of the project root directory.
Fixing that made the test run successfully in PyCharm.
I had this issue - it was simply alignment in the feature file, I had a space on the Scenario definition after 'Scenario' and before the colon. When I removed - the error no longer occured.

Multiple Bokeh Server Integration To Flask

I am trying to run multiple Bokeh servers in the flask app , the plots function correctly on their own using method like this:
def getTimePlot():
script = server_document('http://localhost:5006/timeseries')
return render_template("displaytimeseries.html", script=script, template="Flask")
def startPlotserver():
server.start()
server = Server({'/timeseries': modifyTimeSeries}, io_loop=IOLoop(), allow_websocket_origin=["localhost:8000"])
server.io_loop.start()
if __name__ == '__main__':
print('Opening single process Flask app with embedded Bokeh application on http://localhost:8000/')
print()
print('Multiple connections may block the Bokeh app in this configuration!')
print('See "flask_gunicorn_embed.py" for one way to run multi-process')
app.run(port=5000, debug=True)
but when i try to embed two servers together to flask using this approach that's where i get the problems:
file structure:
|--app4
|---webapp2.py
|---bokeh
|--timeseries.py
|--map.py
I think i have found the workaround in here Link To Question
I am have trying now to import the map server to flak using the similar method mentioned and ended up with something like this:
1. File builder (not sure why it's not picking it up)
def build_single_handler_applications(paths, argvs=None):
applications = {}
argvs = {} or argvs
for path in paths:
application = build_single_handler_application(path, argvs.get(path, []))
route = application.handlers[0].url_path()
if not route:
if '/' in applications:
raise RuntimeError("Don't know the URL path to use for %s" % (path))
route = '/'
applications[route] = application
return applications
2. Code to find file and create connection
files=[]
for file in os.listdir("bokeh"):
if file.endswith('.py'):
file="map"+file
files.append(file)
argvs = {}
urls = []
for i in files:
argvs[i] = None
urls.append(i.split('\\')[-1].split('.')[0])
host = 'http://localhost:5006/map'
apps = build_single_handler_applications(files, argvs)
bokeh_tornado = BokehTornado(apps, extra_websocket_origins=["localhost:8000"])
bokeh_http = HTTPServer(bokeh_tornado)
sockets, port = bind_sockets("localhost:8000", 5000)
bokeh_http.add_sockets(sockets)
3. Code which calls the server and renders template
#app.route('/crimeMap', methods=['GET'])
def getCrimeMap():
bokeh_script = server_document("http://localhost:5006:%d/map" % port)
return render_template("displaymap1.html", bokeh_script=bokeh_script)
i am running both of my Bokeh servers in single command like this
bokeh serve timeseries.py map.py --allow-websocket-origin=127.0.0.1:5000
but when i run webapp2.py i am getting this error:
(env1) C:\Users\Dell1525\Desktop\flaskapp\env1\app4>webapp2.py
Traceback (most recent call last):
File "C:\Users\Dell1525\Desktop\flaskapp\env1\app4\webapp2.py", line 113, in <module>
apps = build_single_handler_applications(files, argvs)
File "C:\Users\Dell1525\Desktop\flaskapp\env1\app4\webapp2.py", line 29, in build_single_handler_applications
application = build_single_handler_application(path, argvs.get(path, []))
NameError: name 'build_single_handler_application' is not defined
i found and added build_single_handler_application function from Bokeh docs only because of this error so i am not sure if it was even required or is correct. I am wondering what am i missing to make this work just in case it is positioning error or missing imports i am attaching full flask webapp2.py code here :
Full Code
Thak you so much for help
i have found an easier solution by tweaking this example a little: Link To Original Post Note this requires you to have tornado 4.4.1 as its not working with newer versions
trick is to run all servers individually and on different ports with same socket access like this
bokeh serve timeseries.py --port 5100 --allow-websocket-origin=localhost:5567
bokeh serve map.py --port 5200 --allow-websocket-origin=localhost:5567
for those who might find this useful i have included full working solution Link To Working Code

How to run Python test case with Appium?

I've created simple test case using Python (in PyCharm editor) which should click on Join/Login button on iOS app, but it doesn't work. Here is the code:
from appium import webdriver
import unittest
import os
class LoginTests(unittest.TestCase):
def setUp(self):
desired_caps = {}
desired_caps['platformName'] = 'iOS'
desired_caps['platformVersion'] = '11.0'
desired_caps['deviceName'] = 'iPhone Simulator' # Run on simulator
desired_caps['bundleId'] = 'com.matchbook.MatchbookApp'
desired_caps['app'] = os.path.abspath('/Users/majdukovic/Library/Developer/Xcode/DerivedData/MatchBook-bgvchkbwrithuaegnjgpoffewdag/Build/Products/Debug-iphonesimulator/MatchBook.app') # Path to .app
self.wd = webdriver.Remote('http://0.0.0.0:4723/wd/hub', desired_caps)
self.wd.implicitly_wait(60)
loginButton = self.wd.find_element_by_id("JOIN/LOGIN") # Button ID
self.assertTrue(loginButton.is_displayed())
loginButton.click()
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(LoginTests)
unittest.TextTestRunner(verbosity=2).run(suite)
If I run this test case it returns:
"Ran 0 tests in 0.000s
OK"
Appium server is already running and app is opened. In PyCharm Preferences I've selected py.test as default test runner.
Details of my setup:
macOS - HighSierra v10.13
Appium desktop app - v1.2.6
Python - v2.7.10
xCode - v9.0.1
Simulator - iPhone 8, iOS v11.0
How about simple code like:
if __name__ == '__main__':
unittest.main()
I'm still not sure what is the problem, I tried a lot of things, but it won't work from Pycharm , so I've written code in Atom editor and run it from Terminal with command:
"python -m py.test name_of_test.py -s" and it works.
Met the same issue. Found out, that "setUp" name is not reads as "test"case.
try this:
def test_testcase1(self):
Testcases should be named like "test_*testcasename_or_whatever*(self)"
File name should be test*.py , For example:
test1.py
Function name should be test*, For example:
def test_testcase1(self):

Django, Firewalls, Selenium, [Errno 10061], and implicitly_wait()

So, I'm quite curious about this one.
I've been trying TDD with Django, and took an exercise out of Harry J.W. Percival's book, as follows:
from selenium import webdriver
import unittest
class NewVisitorTest(unittest.TestCase):
def setUp(self):
self.browser = webdriver.Chrome()
def tearDown(self):
self.browser.quit()
def test_can_start_list_and_retrieve_later(self):
self.browser.get('http://localhost:8000')
self.browser.implicitly_wait(3)
self.assertIn('Django', self.browser.title)
Seems simple enough.
Except I get this failing test:
error: [Errno 10061] No connection could be made because the target machine actively refused it
So I believe I have some kind of Firewall up (which I'd be thankful if you could direct me to). The most curious thing, however is the following:
If I run the script with this one line omitted, however: self.browser.implicitly_wait(3)
The test curiously passes.
When I fail the test, Django says the following:
Not Found: /favicon.ico
[22/Feb/2016 09:34:38] "GET /favicon.ico HTTP/1.1" 404 1940
If this is of any relevance:
OS Is Windows 10
IDE is PyCharm community (so Django is being run in powershell)
Testing framework is Unittest.py
Chrome requires a specific driver that matches the Chrome version which is installed on your machine:
self.browser = webdriver.Chrome("/path/to/chromedriver")
Download the chromedrive and copy it to "/path/to/chromedriver" from https://sites.google.com/a/chromium.org/chromedriver/downloads
Note: For Firefox it's OK to use webdriver.Firefox()

Categories

Resources