summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrédéric van der Essen <fva@openerp.com>2014-02-07 16:50:55 +0100
committerFrédéric van der Essen <fva@openerp.com>2014-02-07 16:50:55 +0100
commit4232de7bf2f19fd01fc9dcccf421eaeba819e586 (patch)
tree5ee2ab75842426634cd0bbc24ed201ae8f08729d
parent34bc74ea422230fd052382e16c0c5e3fcdd26d27 (diff)
parentc254b7ae2cee1a240380880d76f10aeb715a5b37 (diff)
[MERGE] from saas-3
bzr revid: fva@openerp.com-20140207155055-3z8o3fvx2zkoqe91
-rw-r--r--addons/auth_oauth_signup/__openerp__.py6
-rw-r--r--addons/auth_oauth_signup/views/auth_oauth_signup.xml18
-rw-r--r--addons/auth_signup/views/auth_signup_login.xml8
-rw-r--r--addons/email_template/wizard/mail_compose_message_view.xml3
-rw-r--r--addons/gamification/models/challenge.py16
-rw-r--r--addons/gamification/models/goal.py3
-rw-r--r--addons/gamification/models/res_users.py19
-rw-r--r--addons/gamification/views/goal.xml6
-rw-r--r--addons/hr_gamification/__openerp__.py1
-rw-r--r--addons/hr_gamification/views/gamification.xml2
-rw-r--r--addons/website/controllers/main.py2
-rw-r--r--addons/website/models/ir_http.py2
-rw-r--r--addons/website/models/ir_ui_view.py40
-rw-r--r--addons/website/models/website.py47
-rw-r--r--addons/website/static/src/css/website.css15
-rw-r--r--addons/website/static/src/css/website.sass14
-rw-r--r--addons/website/static/src/js/website.editor.js3
-rw-r--r--addons/website/static/src/js/website.snippets.animation.js2
-rw-r--r--addons/website/static/src/js/website.snippets.editor.js21
-rw-r--r--addons/website/static/src/js/website.tests.js40
-rw-r--r--addons/website/static/src/js/website.tour.banner.js85
-rw-r--r--addons/website/static/src/js/website.tour.js147
-rw-r--r--addons/website/static/src/js/website.tour.test.admin.js106
-rw-r--r--addons/website/static/src/js/website.tour.test.js34
-rw-r--r--addons/website/tests/test_ui.py17
-rw-r--r--addons/website/tests/ui_suite/homepage_test.js16
-rw-r--r--addons/website/tests/ui_suite/login_test.js7
-rw-r--r--addons/website/tests/ui_suite/ui_test_runner.js82
-rw-r--r--addons/website/views/snippets.xml2
-rw-r--r--addons/website/views/website_templates.xml7
-rw-r--r--addons/website_blog/static/src/js/website.tour.blog.js82
-rw-r--r--addons/website_blog/tests/ui_suite/post_test.js16
-rw-r--r--addons/website_event/controllers/main.py4
-rw-r--r--addons/website_event/static/src/js/website.tour.event.js71
-rw-r--r--addons/website_event/tests/ui_suite/event_test.js16
-rw-r--r--addons/website_event_sale/static/src/js/website.tour.event_sale.js80
-rw-r--r--addons/website_event_sale/tests/__init__.py1
-rw-r--r--addons/website_event_sale/tests/test_ui.py10
-rw-r--r--addons/website_event_sale/tests/ui_suite/website_event_sale_test.js7
-rw-r--r--addons/website_event_sale/views/website_event_sale.xml7
-rw-r--r--addons/website_sale/controllers/main.py5
-rw-r--r--addons/website_sale/static/src/js/website.tour.sale.js95
-rw-r--r--addons/website_sale/static/src/js/website.tour.shop.js195
-rw-r--r--addons/website_sale/static/src/js/website_sale.js7
-rw-r--r--addons/website_sale/tests/test_ui.py10
-rw-r--r--addons/website_sale/tests/ui_suite/website_sale-add_product-test.js3
-rw-r--r--addons/website_sale/tests/ui_suite/website_sale-sale_process-test-2.js17
-rw-r--r--addons/website_sale/tests/ui_suite/website_sale-sale_process-test.js20
-rw-r--r--addons/website_sale/views/website_sale.xml10
49 files changed, 869 insertions, 558 deletions
diff --git a/addons/auth_oauth_signup/__openerp__.py b/addons/auth_oauth_signup/__openerp__.py
index 8fc93f6c920..d3660f7c052 100644
--- a/addons/auth_oauth_signup/__openerp__.py
+++ b/addons/auth_oauth_signup/__openerp__.py
@@ -2,7 +2,7 @@
##############################################################################
#
# OpenERP, Open Source Management Solution
-# Copyright (C) 2010-2012 OpenERP SA (<http://openerp.com>).
+# Copyright (C) 2010-2014 OpenERP SA (<http://openerp.com>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -30,7 +30,9 @@ Allow users to sign up through OAuth2 Provider.
'author': 'OpenERP SA',
'website': 'http://www.openerp.com',
'depends': ['auth_oauth', 'auth_signup'],
- 'data': [],
+ 'data': [
+ 'views/auth_oauth_signup.xml',
+ ],
'js': [],
'css': [],
'qweb': [],
diff --git a/addons/auth_oauth_signup/views/auth_oauth_signup.xml b/addons/auth_oauth_signup/views/auth_oauth_signup.xml
new file mode 100644
index 00000000000..e6735ebd58a
--- /dev/null
+++ b/addons/auth_oauth_signup/views/auth_oauth_signup.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- vim:et:si:ts=2:sts=2:sw=2 -->
+<openerp>
+ <data>
+ <template id="auth_oauth_signup.signup" inherit_id="auth_signup.signup" name="OAuth Signup buttons">
+ <xpath expr="//button[@type='submit']" position="before">
+ <div class="pull-right">
+ <div t-foreach="providers" t-as="p">
+ <a t-att-href="p['auth_link']" class="btn btn-link">
+ <i t-att-class="p['css_class']"/>
+ <t t-esc="p['body']"/>
+ </a>
+ </div>
+ </div>
+ </xpath>
+ </template>
+ </data>
+</openerp>
diff --git a/addons/auth_signup/views/auth_signup_login.xml b/addons/auth_signup/views/auth_signup_login.xml
index bdc093e3c27..a279528e9ca 100644
--- a/addons/auth_signup/views/auth_signup_login.xml
+++ b/addons/auth_signup/views/auth_signup_login.xml
@@ -5,8 +5,8 @@
<data>
<template id="auth_signup.login" inherit_id="web.login" name="Sign up - Reset Password">
<xpath expr="//button[@type='submit']" position="before">
- <a t-if="signup" t-attf-href="?mode=signup{{ '&amp;debug' if debug else '' }}" class="btn btn-link pull-right">Sign up</a>
- <a t-if="reset" t-attf-href="?mode=reset{{ '&amp;debug' if debug else '' }}" class="btn btn-link pull-right">Reset Password</a>
+ <a t-if="signup" t-attf-href="?{{ keep_query('*', mode='signup') }}" class="btn btn-link pull-right">Sign up</a>
+ <a t-if="reset" t-attf-href="?{{ keep_query('*', mode='reset') }}" class="btn btn-link pull-right">Reset Password</a>
</xpath>
</template>
@@ -29,7 +29,7 @@
<t t-set="reset_without_token" t-value="mode == 'reset' and not token"/>
- <form class="oe_signup_form" role="form" t-attf-action="/web/login{{ '?debug' if debug else '' }}" method="post">
+ <form class="oe_signup_form" role="form" method="post">
<t t-call="web.database_select"/>
<div class="form-group field-name" t-if="not reset_without_token">
@@ -68,7 +68,7 @@
<input type="hidden" name="mode" t-att-value="mode"/>
<input type="hidden" name="token" t-att-value="token"/>
<div class="clearfix oe_login_buttons">
- <a href="/web/login" class="btn btn-link pull-right">Back to Login</a>
+ <a t-attf-href="?{{ keep_query('*', mode='login') }}" class="btn btn-link pull-right">Back to Login</a>
<button type="submit" class="btn btn-primary pull-left">
<t t-if="mode == 'signup'">Sign up</t>
<t t-if="mode == 'reset'">Reset password</t>
diff --git a/addons/email_template/wizard/mail_compose_message_view.xml b/addons/email_template/wizard/mail_compose_message_view.xml
index b7c57af2679..44145114fff 100644
--- a/addons/email_template/wizard/mail_compose_message_view.xml
+++ b/addons/email_template/wizard/mail_compose_message_view.xml
@@ -28,7 +28,8 @@
<div>Use template
<!--FIX: To avoid css issue of many2one field in footer temporary used oe_form (BUG:1152464)-->
<field name="template_id" nolabel="1" class='oe_inline'
- on_change="onchange_template_id(template_id, composition_mode, model, res_id, context)" domain="[('model_id.model','=',model)]"/>
+ on_change="onchange_template_id(template_id, composition_mode, model, res_id, context)" domain="[('model_id.model','=',model)]"
+ context="{'default_model': model, 'default_body_html': body, 'default_subject': subject}"/>
</div>
<button icon="/email_template/static/src/img/email_template_save.png"
type="object" name="save_as_template" string="Save as new template" class="oe_link"
diff --git a/addons/gamification/models/challenge.py b/addons/gamification/models/challenge.py
index ae27aa96719..fec8e04c4b7 100644
--- a/addons/gamification/models/challenge.py
+++ b/addons/gamification/models/challenge.py
@@ -387,6 +387,7 @@ class gamification_challenge(osv.Model):
end_date = challenge.end_date
for line in challenge.line_ids:
+ # FIXME: allow to restrict to a subset of users
for user in challenge.user_ids:
goal_obj = self.pool.get('gamification.goal')
@@ -400,8 +401,9 @@ class gamification_challenge(osv.Model):
# resume canceled goals
domain.append(('state', '=', 'canceled'))
canceled_goal_ids = goal_obj.search(cr, uid, domain, context=context)
- goal_obj.write(cr, uid, canceled_goal_ids, {'state': 'inprogress'}, context=context)
- goal_obj.update(cr, uid, canceled_goal_ids, context=context)
+ if canceled_goal_ids:
+ goal_obj.write(cr, uid, canceled_goal_ids, {'state': 'inprogress'}, context=context)
+ goal_obj.update(cr, uid, canceled_goal_ids, context=context)
# skip to next user
continue
@@ -516,13 +518,6 @@ class gamification_challenge(osv.Model):
domain.append(('user_id', '=', user_id))
sorting = goal_obj._order
limit = 1
- # initialise in case search returns no results
- line_data.update({
- 'id': 0,
- 'current': 0,
- 'completeness': 0,
- 'state': 'draft',
- })
else:
line_data.update({
'own_goal_id': False,
@@ -559,7 +554,8 @@ class gamification_challenge(osv.Model):
'completeness': goal.completeness,
'state': goal.state,
})
- res_lines.append(line_data)
+ if goal_ids:
+ res_lines.append(line_data)
return res_lines
##### Reporting #####
diff --git a/addons/gamification/models/goal.py b/addons/gamification/models/goal.py
index 8792e219d71..8e79c43c8a6 100644
--- a/addons/gamification/models/goal.py
+++ b/addons/gamification/models/goal.py
@@ -163,7 +163,8 @@ class gamification_goal(osv.Model):
string="Challenge",
type='many2one',
relation='gamification.challenge',
- store=True),
+ store=True, readonly=True,
+ help="Challenge that generated the goal, assign challenge to users to generate goals with a value in this field."),
'start_date': fields.date('Start Date'),
'end_date': fields.date('End Date'), # no start and end = always active
'target_goal': fields.float('To Reach',
diff --git a/addons/gamification/models/res_users.py b/addons/gamification/models/res_users.py
index 408ddddf082..d25d725a4ac 100644
--- a/addons/gamification/models/res_users.py
+++ b/addons/gamification/models/res_users.py
@@ -42,6 +42,7 @@ class res_users_gamification_group(osv.Model):
challenge_ids = challenge_obj.search(cr, uid, [('autojoin_group_id', 'in', user_group_ids)], context=context)
if challenge_ids:
challenge_obj.write(cr, uid, challenge_ids, {'user_ids': [(4, user_id) for user_id in ids]}, context=context)
+ challenge_obj.generate_goals_from_challenge(cr, uid, challenge_ids, context=context)
return write_res
def create(self, cr, uid, vals, context=None):
@@ -56,6 +57,7 @@ class res_users_gamification_group(osv.Model):
challenge_ids = challenge_obj.search(cr, uid, [('autojoin_group_id', 'in', user_group_ids)], context=context)
if challenge_ids:
challenge_obj.write(cr, uid, challenge_ids, {'user_ids': [(4, write_res)]}, context=context)
+ challenge_obj.generate_goals_from_challenge(cr, uid, challenge_ids, context=context)
return write_res
# def get_goals_todo_info(self, cr, uid, context=None):
@@ -83,13 +85,15 @@ class res_users_gamification_group(osv.Model):
challenge_ids = challenge_obj.search(cr, uid, [('user_ids', 'in', uid), ('state', '=', 'inprogress')], context=context)
for challenge in challenge_obj.browse(cr, uid, challenge_ids, context=context):
# serialize goals info to be able to use it in javascript
- all_goals_info.append({
- 'id': challenge.id,
- 'name': challenge.name,
- 'visibility_mode': challenge.visibility_mode,
- 'currency': user.company_id.currency_id.id,
- 'lines': challenge_obj._get_serialized_challenge_lines(cr, uid, challenge, user_id, restrict_top=MAX_VISIBILITY_RANKING, context=context),
- })
+ lines = challenge_obj._get_serialized_challenge_lines(cr, uid, challenge, user_id, restrict_top=MAX_VISIBILITY_RANKING, context=context)
+ if lines:
+ all_goals_info.append({
+ 'id': challenge.id,
+ 'name': challenge.name,
+ 'visibility_mode': challenge.visibility_mode,
+ 'currency': user.company_id.currency_id.id,
+ 'lines': lines,
+ })
return all_goals_info
@@ -129,4 +133,5 @@ class res_groups_gamification_group(osv.Model):
challenge_ids = challenge_obj.search(cr, uid, [('autojoin_group_id', 'in', ids)], context=context)
if challenge_ids:
challenge_obj.write(cr, uid, challenge_ids, {'user_ids': [(4, user_id) for user_id in user_ids]}, context=context)
+ challenge_obj.generate_goals_from_challenge(cr, uid, challenge_ids, context=context)
return write_res
diff --git a/addons/gamification/views/goal.xml b/addons/gamification/views/goal.xml
index a269f710c02..1c408e3ab11 100644
--- a/addons/gamification/views/goal.xml
+++ b/addons/gamification/views/goal.xml
@@ -55,7 +55,7 @@
<group string="Reference">
<field name="definition_id" on_change="on_change_definition_id(definition_id)" attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="user_id" attrs="{'readonly':[('state','!=','draft')]}"/>
- <field name="challenge_id" attrs="{'readonly':[('state','!=','draft')]}"/>
+ <field name="challenge_id" />
</group>
<group string="Schedule">
<field name="start_date" attrs="{'readonly':[('state','!=','draft')]}"/>
@@ -280,8 +280,8 @@
<!-- menus in settings - technical feature required -->
<menuitem id="gamification_menu" name="Gamification Tools" parent="base.menu_administration" groups="base.group_no_one" />
- <menuitem id="gamification_goal_menu" parent="gamification_menu" action="goal_list_action" sequence="0"/>
- <menuitem id="gamification_challenge_menu" parent="gamification_menu" action="challenge_list_action" sequence="10"/>
+ <menuitem id="gamification_challenge_menu" parent="gamification_menu" action="challenge_list_action" sequence="0"/>
+ <menuitem id="gamification_goal_menu" parent="gamification_menu" action="goal_list_action" sequence="10"/>
<menuitem id="gamification_definition_menu" parent="gamification_menu" action="goal_definition_list_action" sequence="20"/>
<menuitem id="gamification_badge_menu" parent="gamification_menu" action="badge_list_action" sequence="30"/>
diff --git a/addons/hr_gamification/__openerp__.py b/addons/hr_gamification/__openerp__.py
index c75a4454437..14925421cb1 100644
--- a/addons/hr_gamification/__openerp__.py
+++ b/addons/hr_gamification/__openerp__.py
@@ -37,4 +37,5 @@ Badge received are displayed on the user profile.
'views/gamification.xml',
],
'js': ['static/src/js/gamification.js'],
+ 'auto_install': True,
}
diff --git a/addons/hr_gamification/views/gamification.xml b/addons/hr_gamification/views/gamification.xml
index e2d45948b95..60c758a717d 100644
--- a/addons/hr_gamification/views/gamification.xml
+++ b/addons/hr_gamification/views/gamification.xml
@@ -50,7 +50,7 @@
<field name="view_type">form</field>
<field name="name">Goals History</field>
<field name="view_mode">tree,kanban</field>
- <field name="context">{'search_default_group_by_user': True, 'search_default_group_by_type': True}</field>
+ <field name="context">{'search_default_group_by_user': True, 'search_default_group_by_definition': True}</field>
<field name="domain">[('challenge_id.category', '=', 'hr')]</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py
index 0a3f717740f..a6d8f2982f9 100644
--- a/addons/website/controllers/main.py
+++ b/addons/website/controllers/main.py
@@ -179,6 +179,7 @@ class Website(openerp.addons.web.controllers.main.Home):
result.append({
'name': v.inherit_option_id.name,
'id': v.id,
+ 'xml_id': v.xml_id,
'inherit_id': v.inherit_id.id,
'header': True,
'active': False
@@ -187,6 +188,7 @@ class Website(openerp.addons.web.controllers.main.Home):
result.append({
'name': v.name,
'id': v.id,
+ 'xml_id': v.xml_id,
'inherit_id': v.inherit_id.id,
'header': False,
'active': (v.inherit_id.id == v.inherit_option_id.id) or (not optional and v.inherit_id.id)
diff --git a/addons/website/models/ir_http.py b/addons/website/models/ir_http.py
index 6948f102fec..46b9efc15a8 100644
--- a/addons/website/models/ir_http.py
+++ b/addons/website/models/ir_http.py
@@ -167,5 +167,5 @@ class PageConverter(werkzeug.routing.PathConverter):
for view in views:
xid = xids[view['id']]
- if xid and (not query or query in xid):
+ if xid and (not query or query.lower() in xid.lower()):
yield xid
diff --git a/addons/website/models/ir_ui_view.py b/addons/website/models/ir_ui_view.py
index 95e2179c9ec..f8c0eadbfa9 100644
--- a/addons/website/models/ir_ui_view.py
+++ b/addons/website/models/ir_ui_view.py
@@ -1,8 +1,12 @@
# -*- coding: utf-8 -*-
import copy
+import simplejson
+import werkzeug
from lxml import etree, html
+from openerp.addons.website.models import website
+from openerp.http import request
from openerp.osv import osv, fields
class view(osv.osv):
@@ -117,6 +121,42 @@ class view(osv.osv):
return arch
+ def render(self, cr, uid, id_or_xml_id, values=None, engine='ir.qweb', context=None):
+ if getattr(request, 'website_enabled', False):
+ engine='website.qweb'
+
+ if isinstance(id_or_xml_id, list):
+ id_or_xml_id = id_or_xml_id[0]
+ if isinstance(id_or_xml_id, (int, long)):
+ id_or_xml_id = self.get_view_xmlid(cr, uid, id_or_xml_id)
+
+ if not context:
+ context = {}
+
+ qcontext = context.copy()
+ qcontext.update(
+ website=request.website,
+ url_for=website.url_for,
+ slug=website.slug,
+ res_company=request.website.company_id,
+ user_id=self.pool.get("res.users").browse(cr, uid, uid),
+ )
+
+ # add some values
+ if values:
+ qcontext.update(values)
+
+ # in edit mode ir.ui.view will tag nodes
+ context['inherit_branding'] = qcontext['editable']
+
+ view_obj = request.website.get_template(id_or_xml_id)
+ if 'main_object' not in qcontext:
+ qcontext['main_object'] = view_obj
+
+ values = qcontext
+
+ return super(view, self).render(cr, uid, id_or_xml_id, values=values, engine=engine, context=context)
+
def save(self, cr, uid, res_id, value, xpath=None, context=None):
""" Update a view section. The view section may embed fields to write
diff --git a/addons/website/models/website.py b/addons/website/models/website.py
index 26cf4822a33..e43efa6f0a3 100644
--- a/addons/website/models/website.py
+++ b/addons/website/models/website.py
@@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
-import fnmatch
import inspect
import itertools
import logging
@@ -7,7 +6,6 @@ import math
import re
import urlparse
-import simplejson
import werkzeug
import werkzeug.exceptions
import werkzeug.wrappers
@@ -24,17 +22,6 @@ from openerp.addons.web.http import request, LazyResponse
logger = logging.getLogger(__name__)
-def keep_query(*args, **kw):
- if not args and not kw:
- args = ('*',)
- params = kw.copy()
- query_params = frozenset(werkzeug.url_decode(request.httprequest.query_string).keys())
- for keep_param in args:
- for param in fnmatch.filter(query_params, keep_param):
- if param not in params and param in request.params:
- params[param] = request.params[param]
- return werkzeug.urls.url_encode(params)
-
def url_for(path_or_uri, lang=None):
if isinstance(path_or_uri, unicode):
path_or_uri = path_or_uri.encode('utf-8')
@@ -225,7 +212,6 @@ class website(osv.osv):
request.redirect = lambda url: werkzeug.utils.redirect(url_for(url))
request.context.update(
- is_master_lang=is_master_lang,
editable=is_website_publisher,
translatable=not is_master_lang,
)
@@ -238,37 +224,8 @@ class website(osv.osv):
return self.pool["ir.ui.view"].browse(cr, uid, view_id, context=context)
def _render(self, cr, uid, ids, template, values=None, context=None):
- user = self.pool.get("res.users")
- if not context:
- context = {}
-
- # Take a context
- qweb_values = context.copy()
- # add some values
- if values:
- qweb_values.update(values)
- # fill some defaults
- qweb_values.update(
- request=request,
- json=simplejson,
- website=request.website,
- url_for=url_for,
- keep_query=keep_query,
- slug=slug,
- res_company=request.website.company_id,
- user_id=user.browse(cr, uid, uid),
- quote_plus=werkzeug.url_quote_plus,
- )
- qweb_values.setdefault('editable', False)
-
- # in edit mode ir.ui.view will tag nodes
- context['inherit_branding'] = qweb_values['editable']
-
- view = self.get_template(cr, uid, ids, template)
-
- if 'main_object' not in qweb_values:
- qweb_values['main_object'] = view
- return view.render(qweb_values, engine='website.qweb', context=context)
+ # TODO: remove this. (just kept for backward api compatibility for saas-3)
+ return self.pool['ir.ui.view'].render(cr, uid, template, values=values, context=context)
def render(self, cr, uid, ids, template, values=None, status_code=None, context=None):
def callback(template, values, context):
diff --git a/addons/website/static/src/css/website.css b/addons/website/static/src/css/website.css
index 6610a98d0f1..291051a0986 100644
--- a/addons/website/static/src/css/website.css
+++ b/addons/website/static/src/css/website.css
@@ -1,3 +1,4 @@
+@charset "utf-8";
/* THIS CSS FILE IS FOR WEBSITE THEMING CUSTOMIZATION ONLY
*
* css for editor buttons, openerp widget included in the website and other
@@ -281,12 +282,16 @@ ul.nav-stacked > li > a {
}
/* ---- SNIPPETS --- */
+.oe_img_bg {
+ background-size: 100%;
+}
+
[data-snippet-id], .colmd, .hr, .blockquote {
overflow: hidden;
}
@media (max-width: 400px) {
- [data-snippet-id] {
+ [data-snippet-id]:not([data-snippet-id="carousel"]) {
height: auto !important;
}
}
@@ -295,7 +300,7 @@ ul.nav-stacked > li > a {
}
.carousel-inner .item {
height: 100%;
- background-size: 100%;
+ background-size: cover;
}
.carousel .carousel-caption {
@@ -365,7 +370,7 @@ div.carousel[data-snippet-id="slider"] .carousel-indicators .active {
.parallax {
position: relative;
- background-size: 100%;
+ background-size: cover;
display: table;
width: 100%;
min-height: 100px;
@@ -445,10 +450,6 @@ div.carousel[data-snippet-id="slider"] .carousel-indicators .active {
}
/* Misc */
-.oe_img_bg {
- background-size: 100%;
-}
-
.texttop {
vertical-align: top;
}
diff --git a/addons/website/static/src/css/website.sass b/addons/website/static/src/css/website.sass
index 2c5f691fae6..f4c0b338b6a 100644
--- a/addons/website/static/src/css/website.sass
+++ b/addons/website/static/src/css/website.sass
@@ -228,19 +228,24 @@ ul.nav-stacked > li > a
a
color: white
+
/* ---- SNIPPETS --- */
+
+.oe_img_bg
+ background-size: 100%
+
[data-snippet-id],.colmd,.hr,.blockquote
overflow: hidden
@media (max-width: 400px)
- [data-snippet-id]
+ [data-snippet-id]:not([data-snippet-id="carousel"])
height: auto !important
.carousel-inner
height: 100%
.item
height: 100%
- background-size: 100%
+ background-size: cover
.carousel
.carousel-caption
left: auto
@@ -300,7 +305,7 @@ div.carousel[data-snippet-id="slider"]
.parallax
position: relative
- background-size: 100%
+ background-size: cover
display: table
width: 100%
min-height: 100px
@@ -362,9 +367,6 @@ div.carousel[data-snippet-id="slider"]
/* Misc */
-.oe_img_bg
- background-size: 100%
-
.texttop
vertical-align: top
diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js
index e5ba5018316..1e8246366a9 100644
--- a/addons/website/static/src/js/website.editor.js
+++ b/addons/website/static/src/js/website.editor.js
@@ -414,6 +414,7 @@
openerp.jsonRpc('/website/customize_template_get', 'call', { 'xml_id': view_name }).then(
function(result) {
_.each(result, function (item) {
+ if (item.xml_id === "website.debugger" && !window.location.search.match(/[&?]debug(&|$)/)) return;
if (item.header) {
menu.append('<li class="dropdown-header">' + item.name + '</li>');
} else {
@@ -1082,7 +1083,7 @@
} else {
// Create the page, get the URL back
done = $.get(_.str.sprintf(
- '/pagenew/%s?noredirect=1', encodeURI(data.id)))
+ '/website/add/%s?noredirect=1', encodeURI(data.id)))
.then(function (response) {
self.make_link(response, false, data.id);
});
diff --git a/addons/website/static/src/js/website.snippets.animation.js b/addons/website/static/src/js/website.snippets.animation.js
index 60c5aea49e2..048cf20231f 100644
--- a/addons/website/static/src/js/website.snippets.animation.js
+++ b/addons/website/static/src/js/website.snippets.animation.js
@@ -105,7 +105,7 @@
var offset = 0;
var padding = parseInt($(document.body).css("padding-top"));
if (speed < 1) {
- var inner_offset = self.$target.outerHeight() - this.height / this.width * document.body.clientWidth;
+ var inner_offset = - self.$target.outerHeight() + this.height / this.width * document.body.clientWidth;
var outer_offset = self.$target.offset().top - (document.body.clientHeight - self.$target.outerHeight()) - padding;
offset = - outer_offset * speed + inner_offset;
} else {
diff --git a/addons/website/static/src/js/website.snippets.editor.js b/addons/website/static/src/js/website.snippets.editor.js
index 8a3e7a4421d..e45bee9685b 100644
--- a/addons/website/static/src/js/website.snippets.editor.js
+++ b/addons/website/static/src/js/website.snippets.editor.js
@@ -9,7 +9,7 @@
var self = this;
$("[data-oe-model]").on('click', function (event) {
var $this = $(event.srcElement);
- var tag = $this[0].tagName.toLowerCase();
+ var tag = $this[0] && $this[0].tagName.toLowerCase();
if (!(tag === 'a' || tag === "button") && !$this.parents("a, button").length) {
self.$('[data-action="edit"]').parent().effect('bounce', {distance: 18, times: 5}, 250);
}
@@ -416,6 +416,25 @@
}
setTimeout(function () {
$("#oe_snippets").trigger('snippet-dropped', $target);
+
+ // reset snippet for rte
+ $target.removeData("snippet-editor");
+ if ($target.data("overlay")) {
+ $target.data("overlay").remove();
+ $target.removeData("overlay");
+ }
+ self.create_overlay($target);
+ $target.find("[data-snippet-id]").each(function () {
+ var $snippet = $(this);
+ $snippet.removeData("snippet-editor");
+ if ($snippet.data("overlay")) {
+ $snippet.data("overlay").remove();
+ $snippet.removeData("overlay");
+ }
+ self.create_overlay($snippet);
+ });
+ // end
+
self.make_active($target);
},0);
} else {
diff --git a/addons/website/static/src/js/website.tests.js b/addons/website/static/src/js/website.tests.js
deleted file mode 100644
index 977dc8e1848..00000000000
--- a/addons/website/static/src/js/website.tests.js
+++ /dev/null
@@ -1,40 +0,0 @@
-var tests = {};
-var droptest = function () {
- var errors = [];
- for (var snippet_id in tests) {
- if (!tests[snippet_id]['activated'] || !tests[snippet_id]['dropped']){
- console.log("Can't dropped or activated snippet: " + snippet_id);
- }
- }
- if (errors.length) {
- console.log(tests);
- throw new Error("Can't dropped or activated at least one snippet");
- }
- $("#oe_snippets").off('snippet-activated snippet-dropped');
-};
-var droptesttime = setTimeout(droptest,0);
-
-$("#oe_snippets").off('snippet-activated snippet-dropped')
- .on('snippet-activated', function (event, dom) {
- tests[$(dom).data('src-snippet-id')]['activated'] = true;
- clearTimeout(droptesttime);
- droptesttime = setTimeout(droptest,0);
- })
- .on('snippet-dropped', function (event, dom, src_snipped_id) {
- tests[$(dom).data('src-snippet-id')]['dropped'] = true;
- clearTimeout(droptesttime);
- droptesttime = setTimeout(droptest,0);
- });
-var $thumbnails = $('#oe_snippets div.oe_snippet[data-snippet-id] .oe_snippet_thumbnail');
-$thumbnails.each(function () {
- var $thumbnail = $(this);
- tests[$thumbnail.parent().data('snippet-id')] = {};
- var position = $thumbnail.position();
- $thumbnail.trigger( $.Event( "mousedown", { which: 1, pageX: position.left, pageY: position.top } ) );
- $thumbnail.trigger( $.Event( "mousemove", { which: 1, pageX: position.left+100, pageY: position.top+100 } ) );
- $first_drop = $(".oe_drop_zone").first();
- position = $first_drop.position();
- $first_drop.trigger( $.Event( "mouseup", { which: 1, pageX: position.left+20, pageY: position.top+20 } ) );
- clearTimeout(droptesttime);
- droptesttime = setTimeout(droptest,0);
-});
diff --git a/addons/website/static/src/js/website.tour.banner.js b/addons/website/static/src/js/website.tour.banner.js
index b079c4a670c..c5b04091b40 100644
--- a/addons/website/static/src/js/website.tour.banner.js
+++ b/addons/website/static/src/js/website.tour.banner.js
@@ -2,113 +2,112 @@
'use strict';
var website = openerp.website;
+ var _t = openerp._t;
website.EditorBar.include({
start: function () {
- this.registerTour(new website.BannerTour(this));
+ this.registerTour(new website.Tour.Banner(this));
return this._super();
},
});
- website.BannerTour = website.Tour.extend({
+ website.Tour.Banner = website.Tour.extend({
id: 'banner',
name: "Insert a banner",
path: '/',
- init: function (editor) {
+ init: function () {
var self = this;
self.steps = [
{
- title: "Welcome to your website!",
- content: "This tutorial will guide you to build your home page. We will start by adding a banner.",
- template: self.popover({ next: "Start Tutorial", end: "Skip It" }),
- backdrop: true,
+ title: _t("Welcome to your website!"),
+ content: _t("This tutorial will guide you to build your home page. We will start by adding a banner."),
+ popover: { next: _t("Start Tutorial"), end: _t("Skip It") },
},
{
waitNot: '.popover.tour',
element: 'button[data-action=edit]',
placement: 'bottom',
- title: "Edit this page",
- content: "Every page of your website can be modified through the <i>Edit</i> button.",
- template: self.popover({ fixed: true }),
+ title: _t("Edit this page"),
+ content: _t("Every page of your website can be modified through the <i>Edit</i> button."),
+ popover: { fixed: true },
},
{
element: 'button[data-action=snippet]',
placement: 'bottom',
- title: "Insert building blocks",
- content: "To add content in a page, you can insert building blocks.",
- template: self.popover({ fixed: true }),
+ title: _t("Insert building blocks"),
+ content: _t("To add content in a page, you can insert building blocks."),
+ popover: { fixed: true },
},
{
snippet: 'carousel',
placement: 'bottom',
- title: "Drag & Drop a Banner",
- content: "Drag the Banner block and drop it in your page.",
- template: self.popover({ fixed: true }),
+ title: _t("Drag & Drop a Banner"),
+ content: _t("Drag the Banner block and drop it in your page."),
+ popover: { fixed: true },
},
{
waitFor: '.oe_overlay_options .oe_options:visible',
element: '#wrap [data-snippet-id=carousel]:first .carousel-caption',
- sampleText: 'My Title',
placement: 'top',
- title: "Customize banner's text",
- content: "Click in the text and start editing it. Click continue once it's done.",
- template: self.popover({ next: "Continue" }),
+ title: _t("Customize banner's text"),
+ content: _t("Click in the text and start editing it. Click continue once it's done."),
+ popover: { next: _t("Continue") },
},
{
element: '.oe_overlay_options .oe_options',
placement: 'left',
- title: "Customize the banner",
- content: "Customize any block through this menu. Try to change the background of the banner.",
- template: self.popover({ next: "Continue" }),
+ title: _t("Customize the banner"),
+ content: _t("Customize any block through this menu. Try to change the background of the banner."),
+ popover: { next: _t("Continue") },
},
{
waitNot: '.popover.tour',
element: 'button[data-action=snippet]',
placement: 'bottom',
- title: "Add Another Block",
- content: "Let's add another building block to your page.",
- template: self.popover({ fixed: true }),
+ title: _t("Add Another Block"),
+ content: _t("Let's add another building block to your page."),
+ popover: { fixed: true },
},
{
snippet: 'three-columns',
placement: 'bottom',
- title: "Drag & Drop a Block",
- content: "Drag the <em>'3 Columns'</em> block and drop it below the banner.",
- template: self.popover({ fixed: true }),
+ title: _t("Drag & Drop a Block"),
+ content: _t("Drag the <em>'3 Columns'</em> block and drop it below the banner."),
+ popover: { fixed: true },
},
{
waitFor: '.oe_overlay_options .oe_options:visible',
element: 'button[data-action=save]',
placement: 'right',
- title: "Save your modifications",
- content: "Publish your page by clicking on the <em>'Save'</em> button.",
- template: self.popover({ fixed: true }),
+ title: _t("Save your modifications"),
+ content: _t("Publish your page by clicking on the <em>'Save'</em> button."),
+ popover: { fixed: true },
},
{
waitFor: 'button[data-action=edit]:visible',
- title: "Congratulation!",
- content: "Your homepage has been updated.",
- template: self.popover({ next: "Continue" }),
+ title: _t("Congratulation!"),
+ content: _t("Your homepage has been updated."),
+ popover: { next: _t("Continue") },
},
{
waitNot: '.popover.tour',
element: 'a[data-action=show-mobile-preview]',
placement: 'bottom',
- title: "Test Your Mobile Version",
- content: "Let's check how your homepage looks like on mobile devices.",
- template: self.popover({ fixed: true }),
+ title: _t("Test Your Mobile Version"),
+ content: _t("Let's check how your homepage looks like on mobile devices."),
+ popover: { fixed: true },
},
{
element: 'button[data-dismiss=modal]',
placement: 'right',
- title: "Close Mobile Preview",
- content: "Scroll in the mobile preview to test the rendering. Once it's ok, close this dialog.",
+ title: _t("Close Mobile Preview"),
+ content: _t("Scroll in the mobile preview to test the rendering. Once it's ok, close this dialog."),
},
{
waitNot: '.modal',
- title: "Congrats",
- content: "Congratulation. This tour is finished.",
- template: self.popover({ fixed: true, next: "Close Tutorial" }),
+ title: _t("Congrats"),
+ content: _t("Congratulation. This tour is finished."),
+ popover: { fixed: true, next: _t("Close Tutorial") },
},
];
return this._super();
diff --git a/addons/website/static/src/js/website.tour.js b/addons/website/static/src/js/website.tour.js
index 1db813e4cd4..408a4c01539 100644
--- a/addons/website/static/src/js/website.tour.js
+++ b/addons/website/static/src/js/website.tour.js
@@ -2,8 +2,11 @@
'use strict';
var website = openerp.website;
+
+if (typeof QWeb2 !== "undefined")
website.add_template_file('/website/static/src/xml/website.tour.xml');
+if (website.EditorBar)
website.EditorBar.include({
tours: [],
start: function () {
@@ -17,31 +20,11 @@ website.EditorBar.include({
});
menu.append($menuItem);
});
-
- this.waitRTEReady = false;
- this.on('rte:called', this, function () {self.waitRTEReady = true; });
- this.on('rte:ready', this, function () {self.waitRTEReady = false;});
-
- var res = this._super();
- website.Tour.waitReady.call(this, this.testRunning);
- return res;
+ return this._super();
},
registerTour: function (tour) {
website.Tour.add(tour);
this.tours.push(tour);
- },
- testRunning: function () {
- if (this.waitRTEReady) {
- this.on('rte:ready', this, function () {
- website.Tour.each(function () {
- this.running();
- });
- });
- } else {
- website.Tour.each(function () {
- this.running();
- });
- }
}
});
@@ -78,23 +61,12 @@ $.ajaxSetup({
}
});
-
website.Tour = openerp.Class.extend({
steps: [],
defaultDelay: 50, //ms
+ defaultOverLaps: 5000, //ms
localStorage: window.localStorage,
- init: function (url) {
- this.tour = new Tour({
- name: this.id,
- storage: this.tourStorage,
- keyboard: false,
- template: this.popover(),
- onHide: function () {
- window.scrollTo(0, 0);
- }
- });
- this.registerSteps();
- },
+ init: function () {},
run: function (automatic) {
this.reset();
@@ -105,9 +77,8 @@ website.Tour = openerp.Class.extend({
website.Tour.busy = true;
- if (automatic) {
- this.localStorage.setItem("tour-"+this.id+"-test-automatic", true);
- }
+ this.localStorage.setItem("tour-"+this.id+"-test-automatic", automatic);
+ this.automatic = automatic;
if (this.path) {
// redirect to begin of the tour in function of the language
@@ -123,12 +94,13 @@ website.Tour = openerp.Class.extend({
website.Tour.waitReady.call(this, function () {self._running();});
},
running: function () {
+ var self = this;
if (+this.localStorage.getItem("tour-"+this.id+"-test") >= this.steps.length-1) {
this.endTour();
return;
}
- if (website.Tour.is_busy() || !this.testPathUrl()) return;
+ if (website.Tour.is_busy()) return;
// launch tour with url
this.checkRunningUrl();
@@ -136,6 +108,21 @@ website.Tour = openerp.Class.extend({
// mark tour as busy (only one test running)
if (this.localStorage.getItem("tour-"+this.id+"-test") != null) {
website.Tour.busy = true;
+ this.automatic = !!this.localStorage.getItem("tour-"+this.id+"-test-automatic");
+ }
+
+ if (!this.testPathUrl()) {
+ if (this.automatic) {
+ this.timer = setTimeout(function () {
+ self.reset();
+ throw new Error("Wrong url for running " + self.id
+ + '\ntestPath: ' + self.testPath
+ + '\nhref: ' + window.location.href
+ + "\nreferrer: " + document.referrer
+ );
+ },this.defaultOverLaps);
+ }
+ return;
}
var self = this;
@@ -143,14 +130,10 @@ website.Tour = openerp.Class.extend({
},
_running: function () {
var stepId = this.localStorage.getItem("tour-"+this.id+"-test");
- var automatic = !!this.localStorage.getItem("tour-"+this.id+"-test-automatic");
-
+
if (stepId != null) {
- if (!this.check(this.step(stepId))) {
- var step = this.next(stepId);
- stepId = step ? step.stepId : stepId;
- }
- this.nextStep(stepId, automatic ? this.autoNextStep : null, automatic ? 5000 : null);
+ this.registerTour();
+ this.nextStep(stepId, this.automatic ? this.autoNextStep : null, this.automatic ? this.defaultOverLaps : null);
}
},
@@ -187,20 +170,35 @@ website.Tour = openerp.Class.extend({
}
},
+ registerTour: function () {
+ this.tour = new Tour({
+ name: this.id,
+ storage: this.tourStorage,
+ keyboard: false,
+ template: this.popover(),
+ onHide: function () {
+ window.scrollTo(0, 0);
+ }
+ });
+ this.registerSteps();
+ },
registerSteps: function () {
for (var index=0, len=this.steps.length; index<len; index++) {
var step = this.steps[index];
step.stepId = step.stepId || ""+index;
- if (!step.waitNot && index > 0 && $(this.steps[index-1].template).has("button[data-role='next']").size()) {
- step.waitNot = '.popover.tour';
+ if (!step.waitNot && index > 0 && this.steps[index-1] &&
+ this.steps[index-1].popover && this.steps[index-1].popover.next) {
+ step.waitNot = '.popover.tour:visible';
}
if (!step.waitFor && index > 0 && this.steps[index-1].snippet) {
step.waitFor = '.oe_overlay_options .oe_options:visible';
}
- step._title = step.title;
- step.title = openerp.qweb.render('website.tour_popover_title', { title: step.title });
+ step._title = step._title || step.title;
+ step.title = this.popoverTitle({ title: step._title });
+ step.template = step.template || this.popover( step.popover );
+
if (!step.element) step.orphan = true;
if (step.snippet) {
step.element = '#oe_snippets div.oe_snippet[data-snippet-id="'+step.snippet+'"] .oe_snippet_thumbnail';
@@ -208,9 +206,10 @@ website.Tour = openerp.Class.extend({
}
- if ($(this.steps[index-1].template).has("button[data-role='next']").size()) {
+ if (this.steps[index-1] &&
+ this.steps[index-1].popover && this.steps[index-1].popover.next) {
var step = {
- stepId: index,
+ stepId: ""+index,
waitNot: '.popover.tour:visible'
};
this.steps.push(step);
@@ -219,8 +218,21 @@ website.Tour = openerp.Class.extend({
this.tour.addSteps(this.steps);
},
+ popoverTitle: function (options) {
+ try {
+ return openerp.qweb.render('website.tour_popover_title', options);
+ } catch (e) {
+ if (!this.automatic) throw e;
+ return options.title;
+ }
+ },
popover: function (options) {
- return openerp.qweb.render('website.tour_popover', options);
+ try {
+ return openerp.qweb.render('website.tour_popover', options);
+ } catch (e) {
+ if (!this.automatic) throw e;
+ return "";
+ }
},
timer: null,
@@ -268,7 +280,12 @@ website.Tour = openerp.Class.extend({
self.timer = setTimeout(checkNext, self.defaultDelay);
} else {
self.reset();
- throw new Error("Time overlaps to arrive to step " + step.stepId + ": '" + step._title + "'");
+ throw new Error("Time overlaps to arrive to step " + step.stepId + ": '" + step._title + "'"
+ + '\nelement: ' + Boolean(!step.element || ($(step.element).size() && $(step.element).is(":visible") && !$(step.element).is(":hidden")))
+ + '\nwaitNot: ' + Boolean(!step.waitNot || !$(step.waitNot).size())
+ + '\nwaitFor: ' + Boolean(!step.waitFor || $(step.waitFor).size())
+ + '\n\n' + $("body").html()
+ );
}
}
checkNext();
@@ -291,7 +308,7 @@ website.Tour = openerp.Class.extend({
$(".popover.tour").remove();
// go to step in bootstrap tour
this.tour.goto(index);
- if (step.callback) step.callback();
+ if (step.onload) step.onload();
next = steps.shift();
break;
}
@@ -358,7 +375,10 @@ website.Tour = openerp.Class.extend({
} else if (step.sampleText) {
$element.trigger($.Event("keydown", { srcElement: $element }));
- if ($element.is("select") || $element.is("input") ) {
+ if ($element.is("input") ) {
+ $element.val(step.sampleText);
+ } if ($element.is("select")) {
+ $element.find("[value='"+step.sampleText+"'], option:contains('"+step.sampleText+"')").attr("selected", true);
$element.val(step.sampleText);
} else {
$element.html(step.sampleText);
@@ -404,7 +424,10 @@ website.Tour.busy = false;
website.Tour.add = function (tour) {
website.Tour.waitReady(function () {
tour = tour.id ? tour : new tour();
- website.Tour.tours[tour.id] = tour;
+ if (!website.Tour.tours[tour.id]) {
+ website.Tour.tours[tour.id] = tour;
+ tour.running();
+ }
});
};
website.Tour.get = function (id) {
@@ -420,7 +443,7 @@ website.Tour.each = function (callback) {
website.Tour.waitReady = function (callback) {
var self = this;
$(document).ready(function () {
- if ($.ajaxBusy == null || $.ajaxBusy) {
+ if ($.ajaxBusy) {
$(document).ajaxStop(function() {
setTimeout(function () {
callback.call(self);
@@ -435,18 +458,20 @@ website.Tour.waitReady = function (callback) {
});
};
website.Tour.run_test = function (id) {
- website.Tour.get(id).run(true);
+ website.Tour.waitReady(function () {
+ if (!website.Tour.is_busy()) {
+ website.Tour.tours[id].run(true);
+ }
+ });
};
website.Tour.is_busy = function () {
for (var k in this.localStorage) {
if (!k.indexOf("tour-")) {
- return true;
+ return k;
}
}
return website.Tour.busy;
};
-
-
}());
diff --git a/addons/website/static/src/js/website.tour.test.admin.js b/addons/website/static/src/js/website.tour.test.admin.js
new file mode 100644
index 00000000000..787f05beb23
--- /dev/null
+++ b/addons/website/static/src/js/website.tour.test.admin.js
@@ -0,0 +1,106 @@
+(function () {
+ 'use strict';
+
+ var website = openerp.website;
+
+ website.Tour.LoginEdit = website.Tour.extend({
+ id: 'login_edit',
+ name: "Try to log as admin and check editor",
+ path: '/',
+ init: function () {
+ var self = this;
+ self.steps = [
+ {
+ title: "click login",
+ element: '#top_menu a[href*="/web/login"]',
+ },
+ {
+ title: "insert login",
+ element: '.oe_login_form input[name="login"]',
+ sampleText: "admin",
+ },
+ {
+ title: "insert password",
+ waitFor: '.oe_login_form input[name="login"][value!=""]',
+ element: '.oe_login_form input[name="password"]',
+ sampleText: "admin",
+ },
+ {
+ title: "select 2 Standard tickets",
+ waitFor: '.oe_login_form input[name="password"][value!=""]',
+ element: '.oe_login_form button',
+ },
+ {
+ title: "go back to website from backend",
+ element: 'a[data-action-model="ir.actions.act_url"]:contains("Website")',
+ },
+ {
+ title: 'try to edit',
+ waitNot: '#wrap .carousel',
+ element: 'button[data-action=edit]:visible',
+ },
+ {
+ title: 'check edit mode',
+ waitFor: 'button[data-action=save]:visible',
+ },
+ {
+ title: 'check branding',
+ waitFor: '#wrap[data-oe-model="ir.ui.view"]',
+ },
+ {
+ title: 'check rte',
+ waitFor: '#oe_rte_toolbar',
+ },
+ {
+ title: 'check insert block button',
+ element: '[data-action="snippet"]:visible',
+ },
+ {
+ title: 'add snippets',
+ snippet: 'carousel',
+ },
+ {
+ title: 'try to save',
+ waitFor: '.oe_overlay_options .oe_options:visible',
+ element: 'button[data-action=save]:visible',
+ },
+ {
+ title: 'check saved',
+ waitFor: '#wrap div.carousel',
+ element: 'button[data-action=edit]:visible',
+ },
+ {
+ title: 'try to re-edit',
+ waitFor: 'button[data-action=save]:visible',
+ element: '#wrap .carousel',
+ },
+ {
+ title: 'remove snippet',
+ element: '.oe_snippet_remove',
+ },
+ {
+ title: 'try to re-save',
+ waitNot: '#wrap .carousel',
+ element: 'button[data-action=save]:visible',
+ },
+ {
+ title: "click admin",
+ waitFor: 'button[data-action=edit]:visible',
+ element: 'a:contains("Administrator")',
+ },
+ {
+ title: "click logout",
+ element: '#top_menu a[href*="/logout"]',
+ },
+ {
+ title: "check logout",
+ waitFor: '#top_menu a[href*="/web/login"]',
+ },
+ ];
+ return this._super();
+ },
+ });
+ // for test without editor bar
+ website.Tour.add(website.Tour.LoginEdit);
+
+}());
diff --git a/addons/website/static/src/js/website.tour.test.js b/addons/website/static/src/js/website.tour.test.js
new file mode 100644
index 00000000000..3e85ce20dae
--- /dev/null
+++ b/addons/website/static/src/js/website.tour.test.js
@@ -0,0 +1,34 @@
+(function () {
+
+function LoadScript(src) {
+ xmlHttp = new XMLHttpRequest();
+ xmlHttp.onreadystatechange = function() {
+ if(xmlHttp.readyState == 4) {
+ if (xmlHttp.status == 200 || xmlHttp.status == 304) {
+ new Function(xmlHttp.responseText)();
+ } else {
+ throw new Error("Can't load JavaScript.\nhref: " + window.location.href + "\nsrc: " + src);
+ }
+ }
+ };
+ xmlHttp.open("GET", src, false);
+ xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+ xmlHttp.send(null);
+}
+
+if (typeof jQuery === "undefined")
+ LoadScript("/web/static/lib/jquery/jquery.js");
+if (typeof _ === "undefined")
+ LoadScript("/web/static/lib/underscore/underscore.js");
+if (typeof openerp === "undefined") {
+ LoadScript("/web/static/lib/qweb/qweb2.js");
+ LoadScript("/web/static/src/js/openerpframework.js");
+}
+if (typeof openerp === "undefined" || !openerp.website || !openerp.website.add_template_file)
+ LoadScript("/website/static/src/js/website.js");
+if (typeof Tour === "undefined")
+ LoadScript("/website/static/lib/bootstrap-tour/bootstrap-tour.js");
+if (typeof openerp === "undefined" || !openerp.website.Tour)
+ LoadScript("/website/static/src/js/website.tour.js");
+
+})(); \ No newline at end of file
diff --git a/addons/website/tests/test_ui.py b/addons/website/tests/test_ui.py
index 96484882577..e79a2eb13ec 100644
--- a/addons/website/tests/test_ui.py
+++ b/addons/website/tests/test_ui.py
@@ -41,7 +41,7 @@ class WebsiteUiSuite(unittest.TestSuite):
# timeout in seconds
def __init__(self, testfile, options, timeout=60.0):
self._testfile = testfile
- self._timeout = timeout
+ self._timeout = timeout + 5.0
self._options = options
self._test = None
self._ignore_filters = [
@@ -58,7 +58,6 @@ class WebsiteUiSuite(unittest.TestSuite):
return iter([self])
def run(self, result):
- return
# clean slate
if sql_db._Pool is not None:
sql_db._Pool.close_all(sql_db.dsn(tools.config['db_name']))
@@ -79,18 +78,25 @@ class WebsiteUiSuite(unittest.TestSuite):
del result._exc_info_to_string
def _run(self, result):
- self._test = WebsiteUiTest(self._testfile)
+ self._test = WebsiteUiTest("%s (as %s)" %
+ (self._testfile, self._options.get('user') or "Anonymous" if 'user' in self._options else "admin" ))
start_time = time.time()
last_check_time = time.time()
self._options['timeout'] = self._timeout
self._options['port'] = tools.config.get('xmlrpc_port', 80)
self._options['db'] = tools.config.get('db_name', '')
- self._options['user'] = 'admin'
- self._options['password'] = tools.config.get('admin_passwd', 'admin')
+ # FIX for runbot test
+ if hasattr(os, 'uname') and os.uname()[1].startswith('runbot.'):
+ self._options['host'] = tools.config.get('db_name', '') + ".runbot.openerp.com"
+
+ if 'user' not in self._options:
+ self._options['user'] = 'admin'
+ self._options['password'] = 'admin'
phantom = subprocess.Popen([
'phantomjs',
+ #'--debug=true',
self._testfile,
json.dumps(self._options)
], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
@@ -148,6 +154,7 @@ def full_path(pyfile, filename):
def load_tests(loader, base, _):
base.addTest(WebsiteUiSuite(full_path(__file__, 'dummy_test.js'), {}, 5.0))
+ base.addTest(WebsiteUiSuite(full_path(__file__, 'login_test.js'), {'path': '/', 'user': None}, 60.0))
base.addTest(WebsiteUiSuite(full_path(__file__, 'simple_dom_test.js'), {'redirect': '/page/website.homepage'}, 60.0))
base.addTest(WebsiteUiSuite(full_path(__file__, 'homepage_test.js'), {'redirect': '/page/website.homepage'}, 60.0))
return base
diff --git a/addons/website/tests/ui_suite/homepage_test.js b/addons/website/tests/ui_suite/homepage_test.js
index 2560e5af4d5..9c7375589a6 100644
--- a/addons/website/tests/ui_suite/homepage_test.js
+++ b/addons/website/tests/ui_suite/homepage_test.js
@@ -1,17 +1,3 @@
var testRunner = require('./ui_test_runner.js');
-var waitFor = testRunner.waitFor;
-
-testRunner.run(function homepageTest (page, timeout) {
- page.evaluate(function () { localStorage.clear(); });
- waitFor(function clientReady () {
- return page.evaluate(function () {
- return window.$ && window.openerp && window.openerp.website
- && window.openerp.website.Tour;
- });
- }, function executeTest () {
- page.evaluate(function () {
- window.openerp.website.Tour.run_test('banner');
- });
- }, timeout);
-});
+testRunner.run_test('banner'); \ No newline at end of file
diff --git a/addons/website/tests/ui_suite/login_test.js b/addons/website/tests/ui_suite/login_test.js
new file mode 100644
index 00000000000..3ac403e586d
--- /dev/null
+++ b/addons/website/tests/ui_suite/login_test.js
@@ -0,0 +1,7 @@
+var testRunner = require('./ui_test_runner.js');
+
+testRunner.run_test('login_edit', {
+ "inject": [
+ "./../../../website/static/src/js/website.tour.test.js",
+ "./../../../website/static/src/js/website.tour.test.admin.js"]
+ }); \ No newline at end of file
diff --git a/addons/website/tests/ui_suite/ui_test_runner.js b/addons/website/tests/ui_suite/ui_test_runner.js
index 507a8ca1e72..745adc15f0c 100644
--- a/addons/website/tests/ui_suite/ui_test_runner.js
+++ b/addons/website/tests/ui_suite/ui_test_runner.js
@@ -19,15 +19,15 @@ function waitFor (ready, callback, timeout, timeoutMessageCallback) {
}, 100);
}
-function run (test) {
+function run (test, onload, inject) {
var options = JSON.parse(phantom.args);
- var timeout = options.timeout ? Math.round(parseFloat(options.timeout)*1000) : 60000;
+ var timeout = options.timeout ? Math.round(parseFloat(options.timeout)*1000-5000) : 60000;
var scheme = options.scheme ? options.scheme+'://' : 'http://';
var host = options.host ? options.host : 'localhost';
var port = options.port ? ':'+options.port : '';
- var path = options.path ? options.path : '/login';
+ var path = options.path ? options.path : '/web/login';
var queryParams = [];
if (options.db) queryParams.push('db='+options.db);
@@ -56,24 +56,52 @@ function run (test) {
};
page.onConsoleMessage = function(message) {
console.log(message);
+ try {
+ var result = JSON.parse(message);
+ if (result.event === 'success') {
+ phantom.exit(0);
+ } else if (result.event === 'console') {
+ return;
+ } else {
+ phantom.exit(1);
+ }
+ } catch (exception) {
+ phantom.exit(1);
+ }
};
page.onCallback = function(data) {
if (data.event && data.event === 'start') {
- test(page, timeout);
+ if (test) test(page, timeout, options);
+ }
+ };
+ page.onLoadFinished = function(status) {
+ if (status === "success") {
+ if (inject) {
+ if (!inject instanceof Array) {
+ inject = [inject];
+ }
+ for (var k in inject) {
+ if(!page.injectJs(inject[k])) {
+ console.log("Can't inject "+inject[k]);
+ phantom.exit(1);
+ }
+ }
+ }
+ if (onload) onload(page, timeout, options);
}
};
var maxRetries = 10;
var retryDelay = 1000; // ms
- var tries = 0;
+ var tries = 0;
page.open(url, function openPage (status) {
if (status !== 'success') {
tries++;
if (tries < maxRetries) {
- setTimeout(function () {
- page.open(url, openPage);
- }, retryDelay);
+ setTimeout(function () {
+ page.open(url, openPage);
+ }, retryDelay);
} else {
console.log('{ "event": "error", "message": "'+url+' failed to load '+tries+' times ('+status+')"}');
phantom.exit(1);
@@ -85,9 +113,45 @@ function run (test) {
}
});
+
+ setTimeout(function () {
+ page.evaluate(function (timeout) {
+ var message = ("Timeout after " +(timeout/1000)+ " s"
+ + "\nhref: " + window.location.href
+ + "\nreferrer: " + document.referrer
+ + "\n\n" + document.body.innerHTML).replace(/[^a-z0-9\s~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, "*");
+ console.log(JSON.stringify({ "event": "error", "message": message}));
+ phantom.exit(1);
+ },timeout);
+ }, timeout);
+}
+
+function run_test (testname, options) {
+ options = options || {};
+ run(
+ function start (page, timeout) {
+ page.evaluate(function () { localStorage.clear(); });
+ },
+ function onload (page, timeout) {
+ waitFor(function clientReady () {
+ return page.evaluate(function () {
+ return window.$
+ && window.openerp
+ && window.openerp.website
+ && window.openerp.website.Tour;
+ });
+ }, function executeTest () {
+ page.evaluate(function (testname) {
+ window.openerp.website.Tour.run_test(testname);
+ }, testname);
+ }, timeout);
+ },
+ options.inject || null
+ );
}
module.exports = {
waitFor: waitFor,
- run: run
+ run: run,
+ run_test: run_test
}
diff --git a/addons/website/views/snippets.xml b/addons/website/views/snippets.xml
index 2012340dea1..5d1cd1d30f2 100644
--- a/addons/website/views/snippets.xml
+++ b/addons/website/views/snippets.xml
@@ -903,7 +903,7 @@
</div>
<div data-snippet-style-id='background' data-selector="section, section[data-snippet-id='parallax'], div[data-snippet-id='carousel'], div[data-snippet-id='slider']">
- <li class="dropdown-submenu">
+ <li class="dropdown-submenu" data-required="true">
<a tabindex="-1" href="#">Background</a>
<ul class="dropdown-menu">
<li class="dropdown-submenu">
diff --git a/addons/website/views/website_templates.xml b/addons/website/views/website_templates.xml
index 0f77d7e2914..bf61f64a1b9 100644
--- a/addons/website/views/website_templates.xml
+++ b/addons/website/views/website_templates.xml
@@ -284,6 +284,13 @@
</xpath>
</template>
+<template id="debugger" inherit_option_id="website.layout" name="Debugger &amp; Tests">
+ <xpath expr='//t[@name="layout_head"]' position="after">
+ <script type="text/javascript" src="/website/static/src/js/website.tour.test.js"></script>
+ <script type="text/javascript" src="/website/static/src/js/website.tour.test.admin.js"></script>
+ </xpath>
+</template>
+
<template id="login_layout" inherit_id="web.login_layout" name="Website Login Layout">
<xpath expr="t" position="replace">
<t t-call="website.layout">
diff --git a/addons/website_blog/static/src/js/website.tour.blog.js b/addons/website_blog/static/src/js/website.tour.blog.js
index c943d46e0bb..b6701d74634 100644
--- a/addons/website_blog/static/src/js/website.tour.blog.js
+++ b/addons/website_blog/static/src/js/website.tour.blog.js
@@ -2,115 +2,115 @@
'use strict';
var website = openerp.website;
+ var _t = openerp._t;
website.EditorBar.include({
start: function () {
- this.registerTour(new website.BlogTour(this));
+ this.registerTour(new website.Tour.Blog(this));
return this._super();
},
});
- website.BlogTour = website.Tour.extend({
+ website.Tour.Blog = website.Tour.extend({
id: 'blog',
name: "Create a blog post",
testPath: '/(blog|blogpost)',
- init: function (editor) {
+ init: function () {
var self = this;
self.steps = [
{
- title: "New Blog Post",
- content: "Let's go through the first steps to write beautiful blog posts.",
- template: self.popover({ next: "Start Tutorial", end: "Skip" }),
+ title: _t("New Blog Post"),
+ content: _t("Let's go through the first steps to write beautiful blog posts."),
+ popover: { next: _t("Start Tutorial"), end: _t("Skip") },
},
{
element: '#content-menu-button',
placement: 'left',
- title: "Add Content",
- content: "Create new pages, blogs, menu items and products through the <em>'Content'</em> menu.",
- template: self.popover({ fixed: true }),
+ title: _t("Add Content"),
+ content: _t("Create new pages, blogs, menu items and products through the <em>'Content'</em> menu."),
+ popover: { fixed: true },
},
{
element: 'a[data-action=new_blog_post]',
placement: 'left',
- title: "New Blog Post",
- content: "Select this menu item to create a new blog post.",
- template: self.popover({ fixed: true }),
+ title: _t("New Blog Post"),
+ content: _t("Select this menu item to create a new blog post."),
+ popover: { fixed: true },
},
{
element: '.modal:has(#editor_new_blog) button.btn-primary',
placement: 'right',
- title: "Create Blog Post",
- content: "Click <em>Continue</em> to create the blog post.",
+ title: _t("Create Blog Post"),
+ content: _t("Click <em>Continue</em> to create the blog post."),
},
{
- waitNot: '.modal',
waitFor: 'body:has(button[data-action=save]:visible):has(.js_blog)',
- title: "Blog Post Created",
- content: "This is your new blog post. Let's edit it.",
- template: self.popover({ next: "Continue" }),
+ title: _t("Blog Post Created"),
+ content: _t("This is your new blog post. Let's edit it."),
+ popover: { next: _t("Continue") },
},
{
element: 'h1[data-oe-expression="blog_post.name"]',
placement: 'bottom',
sampleText: 'New Blog',
- title: "Set a Title",
- content: "Click on this area and set a catchy title for your blog post.",
+ title: _t("Set a Title"),
+ content: _t("Click on this area and set a catchy title for your blog post."),
},
{
waitNot: '#wrap h1[data-oe-model="blog.post"]:contains("Blog Post Title")',
element: 'button[data-action=snippet]',
placement: 'bottom',
- title: "Layout Your Blog Post",
- content: "Use well designed building blocks to structure the content of your blog. Click 'Insert Blocks' to add new content.",
- template: self.popover({ fixed: true }),
+ title: _t("Layout Your Blog Post"),
+ content: _t("Use well designed building blocks to structure the content of your blog. Click 'Insert Blocks' to add new content."),
+ popover: { fixed: true },
},
{
snippet: 'image-text',
placement: 'bottom',
- title: "Drag & Drop a Block",
- content: "Drag the <em>'Image-Text'</em> block and drop it in your page.",
- template: self.popover({ fixed: true }),
+ title: _t("Drag & Drop a Block"),
+ content: _t("Drag the <em>'Image-Text'</em> block and drop it in your page."),
+ popover: { fixed: true },
},
{
element: 'button[data-action=snippet]',
placement: 'bottom',
- title: "Add Another Block",
- content: "Let's add another block to your post.",
- template: self.popover({ fixed: true }),
+ title: _t("Add Another Block"),
+ content: _t("Let's add another block to your post."),
+ popover: { fixed: true },
},
{
snippet: 'text-block',
placement: 'bottom',
- title: "Drag & Drop a block",
- content: "Drag the <em>'Text Block'</em> block and drop it below the image block.",
- template: self.popover({ fixed: true }),
+ title: _t("Drag & Drop a block"),
+ content: _t("Drag the <em>'Text Block'</em> block and drop it below the image block."),
+ popover: { fixed: true },
},
{
element: '.oe_active .oe_snippet_remove',
placement: 'top',
- title: "Delete the Title",
- content: "From this toolbar you can move, duplicate or delete the selected zone. Click on the garbage can image to delete the title.",
+ title: _t("Delete the Title"),
+ content: _t("From this toolbar you can move, duplicate or delete the selected zone. Click on the garbage can image to delete the title."),
},
{
waitNot: '.oe_active .oe_snippet_remove:visible',
element: 'button[data-action=save]',
placement: 'right',
- title: "Save Your Blog",
- content: "Click the <em>Save</em> button to record changes on the page.",
- template: self.popover({ fixed: true }),
+ title: _t("Save Your Blog"),
+ content: _t("Click the <em>Save</em> button to record changes on the page."),
+ popover: { fixed: true },
},
{
waitFor: 'button[data-action=edit]:visible',
element: 'button.btn-danger.js_publish_btn',
placement: 'top',
- title: "Publish Your Post",
- content: "Your blog post is not yet published. You can update this draft version and publish it once you are ready.",
+ title: _t("Publish Your Post"),
+ content: _t("Your blog post is not yet published. You can update this draft version and publish it once you are ready."),
},
{
waitFor: '.js_publish_management button.js_publish_btn.btn-success:visible',
title: "Thanks!",
- content: "This tutorial is finished. To discover more features, improve the content of this page and try the <em>Promote</em> button in the top right menu.",
- template: self.popover({ end: "Close Tutorial" }),
+ content: _t("This tutorial is finished. To discover more features, improve the content of this page and try the <em>Promote</em> button in the top right menu."),
+ popover: { next: _t("Close Tutorial") },
},
];
return this._super();
diff --git a/addons/website_blog/tests/ui_suite/post_test.js b/addons/website_blog/tests/ui_suite/post_test.js
index f8d729bee0b..1152ab1da55 100644
--- a/addons/website_blog/tests/ui_suite/post_test.js
+++ b/addons/website_blog/tests/ui_suite/post_test.js
@@ -1,17 +1,3 @@
var testRunner = require('../../../website/tests/ui_suite/ui_test_runner.js');
-var waitFor = testRunner.waitFor;
-
-testRunner.run(function blogTest (page, timeout) {
- page.evaluate(function () { localStorage.clear(); });
- waitFor(function clientReady () {
- return page.evaluate(function () {
- return window.$ && window.openerp && window.openerp.website
- && window.openerp.website.Tour;
- });
- }, function executeTest () {
- page.evaluate(function () {
- window.openerp.website.Tour.run_test('blog');
- });
- }, timeout);
-}); \ No newline at end of file
+testRunner.run_test('blog'); \ No newline at end of file
diff --git a/addons/website_event/controllers/main.py b/addons/website_event/controllers/main.py
index e7e0b4ec9ff..2a6e1d134e3 100644
--- a/addons/website_event/controllers/main.py
+++ b/addons/website_event/controllers/main.py
@@ -203,7 +203,9 @@ class website_event(http.Controller):
def add_event(self, event_name="New Event", **kwargs):
return self._add_event(event_name, request.context, **kwargs)
- def _add_event(self, event_name="New Event", context={}, **kwargs):
+ def _add_event(self, event_name=None, context={}, **kwargs):
+ if not event_name:
+ event_name = _("New Event")
Event = request.registry.get('event.event')
date_begin = datetime.today() + timedelta(days=(14))
vals = {
diff --git a/addons/website_event/static/src/js/website.tour.event.js b/addons/website_event/static/src/js/website.tour.event.js
index c84c0b36bb6..73510b455dd 100644
--- a/addons/website_event/static/src/js/website.tour.event.js
+++ b/addons/website_event/static/src/js/website.tour.event.js
@@ -2,6 +2,7 @@
'use strict';
var website = openerp.website;
+ var _t = openerp._t;
website.EditorBar.include({
start: function () {
@@ -18,93 +19,93 @@
var self = this;
self.steps = [
{
- title: "Create an Event",
- content: "Let's go through the first steps to publish a new event.",
- template: self.popover({ next: "Start Tutorial", end: "Skip It" }),
+ title: _t("Create an Event"),
+ content: _t("Let's go through the first steps to publish a new event."),
+ popover: { next: _("Start Tutorial"), end: _("Skip It") },
},
{
element: '#content-menu-button',
placement: 'left',
- title: "Add Content",
- content: "The <em>Content</em> menu allows you to create new pages, events, menus, etc.",
- template: self.popover({ fixed: true }),
+ title: _t("Add Content"),
+ content: _t("The <em>Content</em> menu allows you to create new pages, events, menus, etc."),
+ popover: { fixed: true },
},
{
element: 'a[data-action=new_event]',
placement: 'left',
- title: "New Event",
- content: "Click here to create a new event.",
- template: self.popover({ fixed: true }),
+ title: _t("New Event"),
+ content: _t("Click here to create a new event."),
+ popover: { fixed: true },
},
{
element: '.modal #editor_new_event input[type=text]',
sampleText: 'Advanced Technical Training',
placement: 'right',
- title: "Create an Event Name",
- content: "Create a name for your new event and click <em>'Continue'</em>. e.g: Technical Training",
+ title: _t("Create an Event Name"),
+ content: _t("Create a name for your new event and click <em>'Continue'</em>. e.g: Technical Training"),
},
{
waitNot: '.modal input[type=text]:not([value!=""])',
element: '.modal button.btn-primary',
placement: 'right',
- title: "Create Event",
- content: "Click <em>Continue</em> to create the event.",
+ title: _t("Create Event"),
+ content: _t("Click <em>Continue</em> to create the event."),
},
{
waitFor: 'body:has(button[data-action=save]:visible):has(.js_event)',
- title: "New Event Created",
- content: "This is your new event page. We will edit the event presentation page.",
- template: self.popover({ next: "Continue" }),
+ title: _t("New Event Created"),
+ content: _t("This is your new event page. We will edit the event presentation page."),
+ popover: { next: _t("Continue") },
},
{
element: 'button[data-action=snippet]',
placement: 'bottom',
- title: "Layout your event",
- content: "Insert blocks to layout the body of your event.",
- template: self.popover({ fixed: true }),
+ title: _t("Layout your event"),
+ content: _t("Insert blocks to layout the body of your event."),
+ popover: { fixed: true },
},
{
snippet: 'image-text',
placement: 'bottom',
- title: "Drag & Drop a block",
- content: "Drag the 'Image-Text' block and drop it in your page.",
- template: self.popover({ fixed: true }),
+ title: _t("Drag & Drop a block"),
+ content: _t("Drag the 'Image-Text' block and drop it in your page."),
+ popover: { fixed: true },
},
{
element: 'button[data-action=snippet]',
placement: 'bottom',
- title: "Layout your event",
- content: "Insert another block to your event.",
- template: self.popover({ fixed: true }),
+ title: _t("Layout your event"),
+ content: _t("Insert another block to your event."),
+ popover: { fixed: true },
},
{
snippet: 'text-block',
placement: 'bottom',
- title: "Drag & Drop a block",
- content: "Drag the 'Text Block' in your event page.",
- template: self.popover({ fixed: true }),
+ title: _t("Drag & Drop a block"),
+ content: _t("Drag the 'Text Block' in your event page."),
+ popover: { fixed: true },
},
{
element: 'button[data-action=save]',
placement: 'right',
- title: "Save your modifications",
- content: "Once you click on save, your event is updated.",
- template: self.popover({ fixed: true }),
+ title: _t("Save your modifications"),
+ content: _t("Once you click on save, your event is updated."),
+ popover: { fixed: true },
},
{
waitFor: 'button[data-action=edit]:visible',
element: 'button.btn-danger.js_publish_btn',
placement: 'top',
- title: "Publish your event",
- content: "Click to publish your event.",
+ title: _t("Publish your event"),
+ content: _t("Click to publish your event."),
},
{
waitFor: '.js_publish_management button.js_publish_btn.btn-success:visible',
element: '.js_publish_management button[data-toggle="dropdown"]',
placement: 'left',
- title: "Customize your event",
- content: "Click here to customize your event further.",
+ title: _t("Customize your event"),
+ content: _t("Click here to customize your event further."),
},
{
element: '.js_publish_management ul>li>a:last:visible',
diff --git a/addons/website_event/tests/ui_suite/event_test.js b/addons/website_event/tests/ui_suite/event_test.js
index 06d6dc12b5f..946427b6b6d 100644
--- a/addons/website_event/tests/ui_suite/event_test.js
+++ b/addons/website_event/tests/ui_suite/event_test.js
@@ -1,17 +1,3 @@
var testRunner = require('../../../website/tests/ui_suite/ui_test_runner.js');
-var waitFor = testRunner.waitFor;
-
-testRunner.run(function eventTest (page, timeout) {
- page.evaluate(function () { localStorage.clear(); });
- waitFor(function clientReady () {
- return page.evaluate(function () {
- return window.$ && window.openerp && window.openerp.website
- && window.openerp.website.Tour;
- });
- }, function executeTest () {
- page.evaluate(function () {
- window.openerp.website.Tour.get('event').run(true);
- });
- }, timeout);
-});
+testRunner.run_test('event'); \ No newline at end of file
diff --git a/addons/website_event_sale/static/src/js/website.tour.event_sale.js b/addons/website_event_sale/static/src/js/website.tour.event_sale.js
new file mode 100644
index 00000000000..7991831400c
--- /dev/null
+++ b/addons/website_event_sale/static/src/js/website.tour.event_sale.js
@@ -0,0 +1,80 @@
+(function () {
+ 'use strict';
+
+ var website = openerp.website;
+
+ website.Tour.EventSaleTest = website.Tour.extend({
+ id: 'event_buy_tickets',
+ name: "Try to buy tickets for event",
+ path: '/event',
+ testPath: '/(event|shop)',
+ init: function () {
+ var self = this;
+ self.steps = [
+ {
+ title: "select event",
+ element: 'a[href*="/event"]:contains("Open Days in Los Angeles")',
+ },
+ {
+ title: "go to register page",
+ waitNot: 'a[href*="/event"]:contains("Functional Webinar")',
+ onload: function () {
+ // use onload if website_event_track is installed
+ if (!$('form:contains("Ticket Type")').size()) {
+ window.location.href = $('a[href*="/event"][href*="/register"]').attr("href");
+ }
+ },
+ },
+ {
+ title: "select 2 Standard tickets",
+ element: 'select[name="ticket-1"]',
+ sampleText: '2',
+ },
+ {
+ title: "select 3 VIP tickets",
+ waitFor: 'select[name="ticket-1"] option:contains(2):selected',
+ element: 'select[name="ticket-2"]',
+ sampleText: '3',
+ },
+ {
+ title: "Order Now",
+ waitFor: 'select[name="ticket-2"] option:contains(3):selected',
+ element: 'button.btn-primary:contains("Order Now")',
+ },
+ {
+ title: "Complete checkout",
+ waitFor: '#top_menu .my_cart_quantity:contains(5)',
+ element: 'form[action="/shop/confirm_order/"] button',
+ onload: function (tour) {
+ if ($("input[name='name']").val() === "")
+ $("input[name='name']").val("website_sale-test-shoptest");
+ if ($("input[name='email']").val() === "")
+ $("input[name='email']").val("website_event_sale_test_shoptest@websiteeventsaletest.optenerp.com");
+ $("input[name='phone']").val("123");
+ $("input[name='street']").val("123");
+ $("input[name='city']").val("123");
+ $("input[name='zip']").val("123");
+ $("select[name='country_id']").val("21");
+ },
+ },
+ {
+ title: "select payment",
+ element: '#payment_method label:has(img[title="transfer"]) input',
+ },
+ {
+ title: "Pay Now",
+ waitFor: '#payment_method label:has(input:checked):has(img[title="transfer"])',
+ element: '.oe_sale_acquirer_button button[name="submit"]:visible',
+ },
+ {
+ title: "finish",
+ waitFor: '.oe_website_sale:contains("Thank you for your order")',
+ }
+ ];
+ return this._super();
+ },
+ });
+ // for test without editor bar
+ website.Tour.add(website.Tour.EventSaleTest);
+
+}());
diff --git a/addons/website_event_sale/tests/__init__.py b/addons/website_event_sale/tests/__init__.py
new file mode 100644
index 00000000000..bf8ba6321ad
--- /dev/null
+++ b/addons/website_event_sale/tests/__init__.py
@@ -0,0 +1 @@
+import test_ui
diff --git a/addons/website_event_sale/tests/test_ui.py b/addons/website_event_sale/tests/test_ui.py
new file mode 100644
index 00000000000..1e5d727de92
--- /dev/null
+++ b/addons/website_event_sale/tests/test_ui.py
@@ -0,0 +1,10 @@
+import openerp.addons.website.tests.test_ui as test_ui
+
+def load_tests(loader, base, _):
+ base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'website_event_sale_test.js'),
+ {'redirect': '/page/website.homepage'}))
+ base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'website_event_sale_test.js'),
+ {'redirect': '/page/website.homepage', 'user': 'demo', 'password': 'demo'}))
+ base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'website_event_sale_test.js'),
+ {'path': '/', 'user': None}))
+ return base \ No newline at end of file
diff --git a/addons/website_event_sale/tests/ui_suite/website_event_sale_test.js b/addons/website_event_sale/tests/ui_suite/website_event_sale_test.js
new file mode 100644
index 00000000000..6662c6a2a55
--- /dev/null
+++ b/addons/website_event_sale/tests/ui_suite/website_event_sale_test.js
@@ -0,0 +1,7 @@
+var testRunner = require('../../../website/tests/ui_suite/ui_test_runner.js');
+
+testRunner.run_test('event_buy_tickets', {
+ "inject": [
+ "./../../../website/static/src/js/website.tour.test.js",
+ "./../../../website_event_sale/static/src/js/website.tour.event_sale.js"]
+ }); \ No newline at end of file
diff --git a/addons/website_event_sale/views/website_event_sale.xml b/addons/website_event_sale/views/website_event_sale.xml
index aa56a5542ac..c3e08031ddb 100644
--- a/addons/website_event_sale/views/website_event_sale.xml
+++ b/addons/website_event_sale/views/website_event_sale.xml
@@ -2,6 +2,13 @@
<openerp>
<data>
+<template id="debugger" inherit_id="website.debugger" name="Event Debugger">
+ <xpath expr="//script[last()]" position="after">
+ <script type="text/javascript" src="/website_event_sale/static/src/js/website.tour.event_sale.js"></script>
+ </xpath>
+</template>
+
+
<template id="index" inherit_id="website_event.index" name="Event's Ticket">
<xpath expr="//li[@t-foreach='event_ids']/div/h4" position="before">
<t t-if="event.state in ['draft', 'confirm'] and event.event_ticket_ids">
diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py
index b9119b486ff..5e02def1494 100644
--- a/addons/website_sale/controllers/main.py
+++ b/addons/website_sale/controllers/main.py
@@ -6,6 +6,7 @@ import werkzeug
from openerp import SUPERUSER_ID
from openerp.addons.web import http
from openerp.addons.web.http import request
+from openerp.tools.translate import _
PPG = 20 # Products Per Page
PPR = 4 # Products Per Row
@@ -294,7 +295,9 @@ class Ecommerce(http.Controller):
return werkzeug.utils.redirect(request.httprequest.referrer + "#comments")
@http.route(['/shop/add_product/'], type='http', auth="user", methods=['POST'], website=True, multilang=True)
- def add_product(self, name="New Product", category=0, **post):
+ def add_product(self, name=None, category=0, **post):
+ if not name:
+ name = _("New Product")
Product = request.registry.get('product.product')
product_id = Product.create(request.cr, request.uid, {
'name': name, 'public_categ_id': category
diff --git a/addons/website_sale/static/src/js/website.tour.sale.js b/addons/website_sale/static/src/js/website.tour.sale.js
new file mode 100644
index 00000000000..83696c4e3cb
--- /dev/null
+++ b/addons/website_sale/static/src/js/website.tour.sale.js
@@ -0,0 +1,95 @@
+(function () {
+ 'use strict';
+
+ var website = openerp.website;
+
+ website.Tour.ShopTest = website.Tour.extend({
+ id: 'shop_buy_product',
+ name: "Try to buy products",
+ path: '/shop',
+ testPath: '/shop',
+ init: function () {
+ var self = this;
+ self.steps = [
+ {
+ title: "select ipod",
+ element: '.oe_product_cart a:contains("iPod")',
+ },
+ {
+ title: "select ipod 32Go",
+ element: 'input[name="product_id"]:not([checked])',
+ },
+ {
+ title: "click on add to cart",
+ waitFor: 'input[name="product_id"]:eq(1)[checked]',
+ element: 'form[action="/shop/add_cart/"] button',
+ },
+ {
+ title: "add suggested",
+ element: 'form[action="/shop/add_cart/"] button.btn-link:contains("Add to Cart")',
+ },
+ {
+ title: "add one more iPod",
+ waitFor: '.my_cart_quantity:contains(2)',
+ element: '#mycart_products tr:contains("iPod: 32 Gb") a.js_add_cart_json:eq(1)',
+ },
+ {
+ title: "remove Headphones",
+ waitFor: '#mycart_products tr:contains("iPod: 32 Gb") input.js_quantity[value=2]',
+ element: '#mycart_products tr:contains("Apple In-Ear Headphones") a.js_add_cart_json:first',
+ },
+ {
+ title: "set one iPod",
+ waitNot: '#mycart_products tr:contains("Apple In-Ear Headphones")',
+ element: '#mycart_products input.js_quantity',
+ sampleText: '1',
+ },
+ {
+ title: "go to checkout",
+ waitFor: '#mycart_products input.js_quantity[value=1]',
+ element: 'a[href="/shop/checkout/"]',
+ },
+ {
+ title: "test with input error",
+ element: 'form[action="/shop/confirm_order/"] button',
+ onload: function (tour) {
+ $("input[name='phone']").val("");
+ },
+ },
+ {
+ title: "test without input error",
+ waitFor: 'form[action="/shop/confirm_order/"] .has-error',
+ element: 'form[action="/shop/confirm_order/"] button',
+ onload: function (tour) {
+ if ($("input[name='name']").val() === "")
+ $("input[name='name']").val("website_sale-test-shoptest");
+ if ($("input[name='email']").val() === "")
+ $("input[name='email']").val("website_sale_test_shoptest@websitesaletest.optenerp.com");
+ $("input[name='phone']").val("123");
+ $("input[name='street']").val("123");
+ $("input[name='city']").val("123");
+ $("input[name='zip']").val("123");
+ $("select[name='country_id']").val("21");
+ },
+ },
+ {
+ title: "select payment",
+ element: '#payment_method label:has(img[title="transfer"]) input',
+ },
+ {
+ title: "Pay Now",
+ waitFor: '#payment_method label:has(input:checked):has(img[title="transfer"])',
+ element: '.oe_sale_acquirer_button button[name="submit"]:visible',
+ },
+ {
+ title: "finish",
+ waitFor: '.oe_website_sale:contains("Thank you for your order")',
+ }
+ ];
+ return this._super();
+ },
+ });
+ // for test without editor bar
+ website.Tour.add(website.Tour.ShopTest);
+
+}());
diff --git a/addons/website_sale/static/src/js/website.tour.shop.js b/addons/website_sale/static/src/js/website.tour.shop.js
index ae67d9b8c46..24dd5fd2d66 100644
--- a/addons/website_sale/static/src/js/website.tour.shop.js
+++ b/addons/website_sale/static/src/js/website.tour.shop.js
@@ -2,238 +2,143 @@
'use strict';
var website = openerp.website;
+ var _t = openerp._t;
website.EditorBar.include({
start: function () {
- this.registerTour(new website.EditorShopTour(this));
- var res = this._super();
- return res;
+ this.registerTour(new website.Tour.Shop(this));
+ return this._super();
},
});
- website.EditorShopTour = website.Tour.extend({
+ website.Tour.Shop = website.Tour.extend({
id: 'shop',
name: "Create a product",
testPath: '/shop',
- init: function (editor) {
+ init: function () {
var self = this;
self.steps = [
{
- title: "Welcome to your shop",
- content: "You successfully installed the e-commerce. This guide will help you to create your product and promote your sales.",
- template: self.popover({ next: "Start Tutorial", end: "Skip It" }),
+ title: _t("Welcome to your shop"),
+ content: _t("You successfully installed the e-commerce. This guide will help you to create your product and promote your sales."),
+ popover: { next: _t("Start Tutorial"), end: _t("Skip It") },
},
{
element: '#content-menu-button',
placement: 'left',
- title: "Create your first product",
- content: "Click here to add a new product.",
- template: self.popover({ fixed: true }),
+ title: _t("Create your first product"),
+ content: _t("Click here to add a new product."),
+ popover: { fixed: true },
},
{
element: 'a[data-action=new_product]',
placement: 'left',
- title: "Create a new product",
- content: "Select 'New Product' to create it and manage its properties to boost your sales.",
- template: self.popover({ fixed: true }),
+ title: _t("Create a new product"),
+ content: _t("Select 'New Product' to create it and manage its properties to boost your sales."),
+ popover: { fixed: true },
},
{
element: '.modal #editor_new_product input[type=text]',
sampleText: 'New Product',
placement: 'right',
- title: "Choose name",
- content: "Enter a name for your new product then click 'Continue'.",
+ title: _t("Choose name"),
+ content: _t("Enter a name for your new product then click 'Continue'."),
},
{
waitNot: '.modal input[type=text]:not([value!=""])',
element: '.modal button.btn-primary',
placement: 'right',
- title: "Create Product",
- content: "Click <em>Continue</em> to create the product.",
+ title: _t("Create Product"),
+ content: _t("Click <em>Continue</em> to create the product."),
},
{
waitFor: 'body:has(button[data-action=save]:visible):has(.js_sale)',
- title: "New product created",
- content: "This page contains all the information related to the new product.",
- template: self.popover({ next: "Continue" }),
+ title: _t("New product created"),
+ content: _t("This page contains all the information related to the new product."),
+ popover: { next: _t("Continue") },
},
{
element: '.product_price .oe_currency_value',
sampleText: '20.50',
placement: 'left',
- title: "Change the price",
- content: "Edit the price of this product by clicking on the amount.",
+ title: _t("Change the price"),
+ content: _t("Edit the price of this product by clicking on the amount."),
},
{
waitNot: '.product_price .oe_currency_value:containsExact(1.00)',
element: '#wrap img.img:first',
placement: 'top',
- title: "Update image",
- content: "Click here to set an image describing your product.",
+ title: _t("Update image"),
+ content: _t("Click here to set an image describing your product."),
},
{
element: 'button.hover-edition-button:visible',
placement: 'top',
- title: "Update image",
- content: "Click here to set an image describing your product.",
+ title: _t("Update image"),
+ content: _t("Click here to set an image describing your product."),
},
{
wait: 500,
element: '.well a.pull-right',
placement: 'bottom',
- title: "Select an Image",
- content: "Let's select an existing image.",
- template: self.popover({ fixed: true }),
+ title: _t("Select an Image"),
+ content: _t("Let's select an existing image."),
+ popover: { fixed: true },
},
{
element: 'img[alt=imac]',
placement: 'bottom',
- title: "Select an Image",
- content: "Let's select an imac image.",
- template: self.popover({ fixed: true }),
+ title: _t("Select an Image"),
+ content: _t("Let's select an imac image."),
+ popover: { fixed: true },
},
{
waitNot: 'img[alt=imac]',
element: '.modal-content button.save',
placement: 'bottom',
- title: "Select this Image",
- content: "Click to add the image to the product decsription.",
- template: self.popover({ fixed: true }),
+ title: _t("Select this Image"),
+ content: _t("Click to add the image to the product decsription."),
+ popover: { fixed: true },
},
{
waitNot: '.modal-content:visible',
element: 'button[data-action=snippet]',
placement: 'bottom',
- title: "Describe the Product",
- content: "Insert blocks like text-image, or gallery to fully describe the product.",
- template: self.popover({ fixed: true }),
+ title: _t("Describe the Product"),
+ content: _t("Insert blocks like text-image, or gallery to fully describe the product."),
+ popover: { fixed: true },
},
{
snippet: 'big-picture',
placement: 'bottom',
- title: "Drag & Drop a block",
- content: "Drag the 'Big Picture' block and drop it in your page.",
- template: self.popover({ fixed: true }),
+ title: _t("Drag & Drop a block"),
+ content: _t("Drag the 'Big Picture' block and drop it in your page."),
+ popover: { fixed: true },
},
{
element: 'button[data-action=save]',
placement: 'right',
- title: "Save your modifications",
- content: "Once you click on save, your product is updated.",
- template: self.popover({ fixed: true }),
+ title: _t("Save your modifications"),
+ content: _t("Once you click on save, your product is updated."),
+ popover: { fixed: true },
},
{
waitFor: '#website-top-navbar button[data-action="edit"]:visible',
element: '.js_publish_management button.js_publish_btn.btn-danger',
placement: 'top',
- title: "Publish your product",
- content: "Click to publish your product so your customers can see it.",
+ title: _t("Publish your product"),
+ content: _t("Click to publish your product so your customers can see it."),
},
{
waitFor: '.js_publish_management button.js_publish_btn.btn-success:visible',
- title: "Congratulations",
- content: "Congratulations! You just created and published your first product.",
- template: self.popover({ next: "Close Tutorial" }),
+ title: _t("Congratulations"),
+ content: _t("Congratulations! You just created and published your first product."),
+ popover: { next: _t("Close Tutorial") },
},
];
return this._super();
}
});
- website.EditorShopTest = website.Tour.extend({
- id: 'shop_buy_product',
- name: "Try to buy products",
- path: '/shop',
- testPath: '/shop',
- init: function (editor) {
- var self = this;
- self.steps = [
- {
- title: 'begin-test',
- template: self.popover({ next: "Start Test"}),
- backdrop: true,
- },
- {
- title: "select ipod",
- element: '.oe_product_cart a:contains("iPod")',
- },
- {
- title: "select ipod 32Go",
- element: 'input[name="product_id"]:not([checked])',
- },
- {
- title: "click on add to cart",
- waitFor: 'input[name="product_id"]:eq(1)[checked]',
- element: 'form[action="/shop/add_cart/"] button',
- },
- {
- title: "add suggested",
- element: 'form[action="/shop/add_cart/"] button.btn-link:contains("Add to Cart")',
- },
- {
- title: "add one more iPod",
- waitFor: '.my_cart_quantity:contains(2)',
- element: '#mycart_products tr:contains("iPod: 32 Gb") a.js_add_cart_json:eq(1)',
- },
- {
- title: "remove Headphones",
- waitFor: '#mycart_products tr:contains("iPod: 32 Gb") input.js_quantity[value=2]',
- element: '#mycart_products tr:contains("Apple In-Ear Headphones") a.js_add_cart_json:first',
- },
- {
- title: "set one iPod",
- waitNot: '#mycart_products tr:contains("Apple In-Ear Headphones")',
- element: '#mycart_products input.js_quantity',
- sampleText: '1',
- },
- {
- title: "go to checkout",
- waitFor: '#mycart_products input.js_quantity[value=1]',
- element: 'a[href="/shop/checkout/"]',
- },
- {
- title: "test with input error",
- element: 'form[action="/shop/confirm_order/"] button',
- callback: function (tour) {
- $("input[name='phone']").val("");
- },
- },
- {
- title: "test without input error",
- waitFor: 'form[action="/shop/confirm_order/"] .has-error',
- element: 'form[action="/shop/confirm_order/"] button',
- callback: function (tour) {
- if ($("input[name='name']").val() === "")
- $("input[name='name']").val("website_sale-test-shoptest");
- if ($("input[name='email']").val() === "")
- $("input[name='email']").val("website_sale-test-shoptest@website_sale-test-shoptest.optenerp.com");
- $("input[name='phone']").val("123");
- $("input[name='street']").val("123");
- $("input[name='city']").val("123");
- $("input[name='zip']").val("123");
- $("select[name='country_id']").val("21");
- },
- },
- {
- title: "select acquirer",
- element: 'input[name="acquirer"]:first',
- },
- {
- title: "Pay Now",
- element: 'button:contains("Pay Now")',
- },
- {
- title: "finish",
- waitFor: '.oe_website_sale:contains("Thank you for your order")',
- }
- ];
- return this._super();
- },
- });
- // for test without editor bar
- $(document).ready(function () {
- website.Tour.add(website.EditorShopTest);
- });
-
}());
diff --git a/addons/website_sale/static/src/js/website_sale.js b/addons/website_sale/static/src/js/website_sale.js
index 7f6d24373f7..3c9bb6ea05c 100644
--- a/addons/website_sale/static/src/js/website_sale.js
+++ b/addons/website_sale/static/src/js/website_sale.js
@@ -26,11 +26,12 @@ $(document).ready(function () {
if (isNaN(value)) value = 0;
openerp.jsonRpc("/shop/set_cart_json/", 'call', {'order_line_id': $input.data('id'), 'set_number': value})
.then(function (data) {
- set_my_cart_quantity(data[1]);
- $input.val(data[0]);
- if (!data[0]) {
+ if (!data) {
location.reload();
+ return;
}
+ set_my_cart_quantity(data[1]);
+ $input.val(data[0]);
});
});
diff --git a/addons/website_sale/tests/test_ui.py b/addons/website_sale/tests/test_ui.py
index 72b948830b1..394a9ca8e4f 100644
--- a/addons/website_sale/tests/test_ui.py
+++ b/addons/website_sale/tests/test_ui.py
@@ -1,8 +1,12 @@
import openerp.addons.website.tests.test_ui as test_ui
def load_tests(loader, base, _):
+ base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'website_sale-add_product-test.js'),
+ {'redirect': '/page/website.homepage'}))
base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'website_sale-sale_process-test.js'),
- { 'action': 'website.action_website_homepage' }))
- base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'website_sale-sale_process-test-2.js'),
- { 'action': 'website.action_website_homepage' }))
+ {'redirect': '/page/website.homepage'}))
+ base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'website_sale-sale_process-test.js'),
+ {'redirect': '/page/website.homepage', 'user': 'demo', 'password': 'demo'}))
+ base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'website_sale-sale_process-test.js'),
+ {'path': '/', 'user': None}))
return base \ No newline at end of file
diff --git a/addons/website_sale/tests/ui_suite/website_sale-add_product-test.js b/addons/website_sale/tests/ui_suite/website_sale-add_product-test.js
new file mode 100644
index 00000000000..24befb7f15d
--- /dev/null
+++ b/addons/website_sale/tests/ui_suite/website_sale-add_product-test.js
@@ -0,0 +1,3 @@
+var testRunner = require('../../../website/tests/ui_suite/ui_test_runner.js');
+
+testRunner.run_test('shop'); \ No newline at end of file
diff --git a/addons/website_sale/tests/ui_suite/website_sale-sale_process-test-2.js b/addons/website_sale/tests/ui_suite/website_sale-sale_process-test-2.js
deleted file mode 100644
index c55eec11617..00000000000
--- a/addons/website_sale/tests/ui_suite/website_sale-sale_process-test-2.js
+++ /dev/null
@@ -1,17 +0,0 @@
-var testRunner = require('../../../website/tests/ui_suite/ui_test_runner.js');
-
-var waitFor = testRunner.waitFor;
-
-testRunner.run(function websiteSaleTest (page, timeout) {
- page.evaluate(function () { localStorage.clear(); });
- waitFor(function clientReady () {
- return page.evaluate(function () {
- return window.$ && window.openerp && window.openerp.website
- && window.openerp.website.Tour;
- });
- }, function executeTest () {
- page.evaluate(function () {
- window.openerp.website.Tour.run_test('shop');
- });
- }, timeout);
-});
diff --git a/addons/website_sale/tests/ui_suite/website_sale-sale_process-test.js b/addons/website_sale/tests/ui_suite/website_sale-sale_process-test.js
index 5611d8400de..ca3943d5e85 100644
--- a/addons/website_sale/tests/ui_suite/website_sale-sale_process-test.js
+++ b/addons/website_sale/tests/ui_suite/website_sale-sale_process-test.js
@@ -1,17 +1,7 @@
var testRunner = require('../../../website/tests/ui_suite/ui_test_runner.js');
-var waitFor = testRunner.waitFor;
-
-testRunner.run(function websiteSaleTest (page, timeout) {
- page.evaluate(function () { localStorage.clear(); });
- waitFor(function clientReady () {
- return page.evaluate(function () {
- return window.$ && window.openerp && window.openerp.website
- && window.openerp.website.Tour;
- });
- }, function executeTest () {
- page.evaluate(function () {
- window.openerp.website.Tour.run_test('shop_buy_product');
- });
- }, timeout);
-}); \ No newline at end of file
+testRunner.run_test('shop_buy_product', {
+ "inject": [
+ "./../../../website/static/src/js/website.tour.test.js",
+ "./../../../website_sale/static/src/js/website.tour.sale.js"]
+ });
diff --git a/addons/website_sale/views/website_sale.xml b/addons/website_sale/views/website_sale.xml
index ed2007e27c7..bd51d35cc14 100644
--- a/addons/website_sale/views/website_sale.xml
+++ b/addons/website_sale/views/website_sale.xml
@@ -4,6 +4,12 @@
<!-- Layout add nav and footer -->
+<template id="debugger" inherit_id="website.debugger" name="Event Debugger">
+ <xpath expr="//script[last()]" position="after">
+ <script type="text/javascript" src="/website_sale/static/src/js/website.tour.sale.js"></script>
+ </xpath>
+</template>
+
<template id="editor_head" inherit_id="website.editor_head" name="Shop Editor" groups="base.group_sale_manager">
<xpath expr="//script[@id='website_tour_js']" position="after">
<script type="text/javascript" src="/website_sale/static/src/js/website_sale.editor.js"></script>
@@ -530,7 +536,7 @@
<a t-if="website_sale_order and website_sale_order.website_order_line" href="/shop/checkout/" class="btn btn-primary pull-right mb32">Process Checkout <span class="fa fa-long-arrow-right"/></a>
<div class="oe_structure"/>
</div>
- <div class="col-lg-3 col-lg-offset-1 col-sm-3 text-muted" id="right_column">
+ <div class="col-lg-3 col-lg-offset-1 col-sm-3 col-md-3 text-muted" id="right_column">
<h4>Policies</h4>
<ul class="list-unstyled mb32">
<li>&#9745; 30-days money-back guarantee</li>
@@ -828,7 +834,7 @@
</div>
<button type="submit" class="btn btn-default btn-primary pull-right mb32">Confirm <span class="fa fa-long-arrow-right"/></button>
</div>
- <div class="col-lg-offset-1 col-lg-3 text-muted">
+ <div class="col-lg-offset-1 col-lg-3 col-md-3 text-muted">
<h3 class="page-header mt16">Your Order <small><a href="/shop/mycart"><span class="fa fa-arrow-right"/> change</a></small></h3>
<div class="row">
<div class="col-sm-6 text-right">Subtotal:</div>