def get_session_from_webdriver(driver: WebDriver, registry: Registry) -> RedisSession: """Extract session cookie from a Selenium driver and fetch a matching pyramid_redis_sesssion data. Example:: def test_newsletter_referral(dbsession, web_server, browser, init): '''Referral is tracker for the newsletter subscription.''' b = browser b.visit(web_server + "/newsletter") with transaction.manager: r = ReferralProgram() r.name = "Foobar program" dbsession.add(r) dbsession.flush() ref_id, slug = r.id, r.slug # Inject referral data to the active session. We do this because it is very hard to spoof external links pointing to localhost test web server. session = get_session_from_webdriver(b.driver, init.config.registry) session["referral"] = { "ref": slug, "referrer": "http://example.com" } session.to_redis() b.fill("email", "*****@*****.**") b.find_by_name("subscribe").click() # Displayed as a message after succesful form subscription assert b.is_text_present("Thank you!") # Check we get an entry with transaction.manager: assert dbsession.query(NewsletterSubscriber).count() == 1 subscription = dbsession.query(NewsletterSubscriber).first() assert subscription.email == "*****@*****.**" assert subscription.ip == "127.0.0.1" assert subscription.referral_program_id == ref_id assert subscription.referrer == "http://example.com" :param driver: The active WebDriver (usually ``browser.driver``) :param registry: The Pyramid registry (usually ``init.config.registry``) """ # Decode the session our test browser is associated with by reading the raw session cookie value and fetching the session object from Redis secret = registry.settings["redis.sessions.secret"] session_cookie = driver.get_cookie("session")["value"] session_id = signed_deserialize(session_cookie, secret) class MockRequest: def __init__(self, registry): self.registry = registry # Use pyramid_redis_session to get a connection to the Redis database redis = get_default_connection(MockRequest(registry)) session = RedisSession(redis, session_id, new=False, new_session=None) return session
def factory(request, initial_data, new_session_id=get_unique_session_id): redis_options = dict( host=host, port=port, db=db, password=password, socket_timeout=socket_timeout, connection_pool=connection_pool, encoding=encoding, encoding_errors=encoding_errors, unix_socket_path=unix_socket_path, ) # an explicit client callable gets priority over the default redis = client_callable(request, **redis_options) \ if client_callable is not None \ else get_default_connection(request, url=url, **redis_options) # attempt to retrieve a session_id from the cookie session_id_from_cookie = _get_session_id_from_cookie( request=request, cookie_name=cookie_name, secret=secret, ) new_session = functools.partial( new_session_id, redis=redis, timeout=timeout, serialize=serialize, generator=id_generator, ) if session_id_from_cookie and redis.exists(session_id_from_cookie): session_id = session_id_from_cookie session_cookie_was_valid = True else: session_id = new_session() session_cookie_was_valid = False session = klass( initial_data, redis=redis, session_id=session_id, new=not session_cookie_was_valid, new_session=new_session, serialize=serialize, deserialize=deserialize, ) set_cookie = functools.partial( _set_cookie, session, cookie_name=cookie_name, cookie_max_age=cookie_max_age, cookie_path=cookie_path, cookie_domain=cookie_domain, cookie_secure=cookie_secure, cookie_httponly=cookie_httponly, secret=secret, ) delete_cookie = functools.partial( _delete_cookie, cookie_name=cookie_name, cookie_path=cookie_path, cookie_domain=cookie_domain, ) cookie_callback = functools.partial( _cookie_callback, session, session_cookie_was_valid=session_cookie_was_valid, cookie_on_exception=cookie_on_exception, set_cookie=set_cookie, delete_cookie=delete_cookie, cookieless_headers=cookieless_headers, ) request.add_response_callback(cookie_callback) return session