├── version.lisp-expr ├── .gitmodules ├── package.lisp ├── weblocks-twitter-bootstrap-application-tests.asd ├── tests.lisp ├── tests-app-updates.lisp └── license.txt /version.lisp-expr: -------------------------------------------------------------------------------- 1 | "0.0.15" 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "jquery-seq"] 2 | path = jquery-seq 3 | url = git://github.com/html/jquery-seq.git 4 | [submodule "weblocks-jquery"] 5 | path = weblocks-jquery 6 | url = git://github.com/html/weblocks-jquery.git 7 | -------------------------------------------------------------------------------- /package.lisp: -------------------------------------------------------------------------------- 1 | (defpackage #:weblocks-twitter-bootstrap-application-tests 2 | (:use #:cl #:weblocks #:weblocks-selenium-tests #:weblocks-twitter-bootstrap-application #:weblocks-selenium-tests-app #:selenium #:weblocks-utils) 3 | (:export #:with-new-or-existing-selenium-session-on-bootstrap-site #:define-bootstrap-demo-action)) 4 | 5 | -------------------------------------------------------------------------------- /weblocks-twitter-bootstrap-application-tests.asd: -------------------------------------------------------------------------------- 1 | ;;;; weblocks-twitter-bootstrap-application.asd 2 | 3 | (asdf:defsystem #:weblocks-twitter-bootstrap-application-tests 4 | :serial t 5 | :description "Demo app for weblocks-twitter-bootstrap-application" 6 | :author "Olexiy Zamkoviy " 7 | :license "LLGPL" 8 | :version (:read-from-file "version.lisp-expr") 9 | :depends-on (#:weblocks-twitter-bootstrap-application #:weblocks-selenium-tests #:weblocks-utils) 10 | :components 11 | ((:file "package") 12 | (:file "tests-app-updates" :depends-on ("package")) 13 | (:file "tests" :depends-on ("tests-app-updates")))) 14 | 15 | -------------------------------------------------------------------------------- /tests.lisp: -------------------------------------------------------------------------------- 1 | (in-package :weblocks-twitter-bootstrap-application-tests) 2 | 3 | (def-test-suite weblocks-twitter-bootstrap-application-tests) 4 | 5 | (defun sample-dialog-assertions () 6 | (do-screen-state-test "bootstrap/shows-dialog" :wait-after-resize 1000) 7 | (is (string= "Dialog title" (do-get-text "css=.modal-header h3"))) 8 | (is (string= "Some dialog content" (do-get-text "css=div.modal-body p"))) 9 | (is (string= "Close dialog" (do-get-text "css=div.modal-body a")))) 10 | 11 | (deftest shows-dialog () 12 | (with-new-or-existing-selenium-session-on-bootstrap-site 13 | (do-click-and-wait "link=Dialog") 14 | (sample-dialog-assertions) 15 | (do-click-and-wait "link=Close dialog"))) 16 | 17 | (deftest shows-dialog-after-page-reloading () 18 | (with-new-or-existing-selenium-session-on-bootstrap-site 19 | (do-click-and-wait "link=Dialog") 20 | (sample-dialog-assertions) 21 | (do-refresh) 22 | (do-open-and-wait *site-url*) 23 | (sleep 1) ; waiting for dialog to do all effects 24 | (sample-dialog-assertions) 25 | (do-click-and-wait "link=Close dialog"))) 26 | 27 | (deftest does-not-display-hidden-field () 28 | (with-new-or-existing-selenium-session-on-bootstrap-site 29 | (do-click-and-wait "link=Hidden field") 30 | (handler-case 31 | (progn 32 | (do-get-text "css=.some-field") 33 | (error "There should not be div with class some-field")) 34 | (execution-error ())) 35 | (do-click-and-wait "name=cancel"))) 36 | 37 | (deftest shows-gridedit () 38 | (with-new-or-existing-selenium-session-on-bootstrap-site 39 | (delete-all 'test-model :store *bootstrap-tests-store*) 40 | (do-click-and-wait "link=Gridedit") 41 | (do-screen-state-test "bootstrap/gridedit" :wait-after-resize 1000) 42 | (do-click-and-wait "link=Back"))) 43 | 44 | (deftest shows-gridedit-with-pagination () 45 | (with-new-or-existing-selenium-session-on-bootstrap-site 46 | (delete-all 'test-model :store *bootstrap-tests-store*) 47 | 48 | (loop for i from 1 to 30 do 49 | (persist-object *bootstrap-tests-store* (make-instance 'test-model :title "Test" :content "Test"))) 50 | 51 | (do-click-and-wait "link=Gridedit") 52 | 53 | (do-screen-state-test "bootstrap/gridedit-filled-first-page" :wait-after-resize 1000) 54 | 55 | (do-click-and-wait "css=.next-page") 56 | 57 | (do-screen-state-test "bootstrap/gridedit-filled-last-page" :wait-after-resize 1000) 58 | 59 | (do-click-and-wait "link=Back"))) 60 | 61 | (deftest adds-items-to-gridedit-and-shows-flash () 62 | (with-new-or-existing-selenium-session-on-bootstrap-site 63 | (delete-all 'test-model :store *bootstrap-tests-store*) 64 | 65 | (do-click-and-wait "link=Gridedit") 66 | 67 | (do-click-and-wait "name=add") 68 | (do-screen-state-test "bootstrap/gridedit-add-form-1" :wait-after-resize 1000) 69 | (do-type "name=title" "Test") 70 | (do-type "name=content" "Test") 71 | (do-click-and-wait "name=submit") 72 | 73 | (do-click-and-wait "name=add") 74 | (do-screen-state-test "bootstrap/gridedit-add-form-2" :wait-after-resize 1000) 75 | (do-type "name=title" "Test") 76 | (do-type "name=content" "Test") 77 | (do-click-and-wait "name=submit") 78 | 79 | (do-screen-state-test "bootstrap/gridedit-add-form-flash-showed" :wait-after-resize 1000) 80 | 81 | (do-click-and-wait "link=Back"))) 82 | 83 | (deftest shows-choices () 84 | (with-new-or-existing-selenium-session-on-bootstrap-site 85 | (do-click-and-wait "link=Choices") 86 | (do-screen-state-test "bootstrap/choices" :wait-after-resize 1000) 87 | (do-click-and-wait "name=ok"))) 88 | 89 | (deftest shows-hidden-field () 90 | (with-new-or-existing-selenium-session-on-bootstrap-site 91 | (do-click-and-wait "link=Hidden field") 92 | (do-screen-state-test "bootstrap/hidden-field" :wait-after-resize 1000) 93 | (do-click-and-wait "name=cancel"))) 94 | 95 | (deftest shows-checkbox-fields () 96 | (with-new-or-existing-selenium-session-on-bootstrap-site 97 | (do-click-and-wait "link=Checkbox fields") 98 | (do-screen-state-test "bootstrap/checkbox-fields" :wait-after-resize 1000) 99 | (do-click-and-wait "name=cancel"))) 100 | 101 | (deftest changes-navbar-selector-tabs () 102 | (with-new-or-existing-selenium-session-on-bootstrap-site 103 | (do-click-and-wait "link=Navbar selector") 104 | (is (string= "First tab" (do-get-text "css=.simple-selector .composite"))) 105 | (do-click-and-wait "link=Second pane") 106 | (is (string= "Second tab" (do-get-text "css=.simple-selector .composite"))) 107 | (do-click-and-wait "link=Third pane") 108 | (is (string= "Third tab" (do-get-text "css=.simple-selector .composite"))) 109 | (do-click-and-wait "link=back") 110 | (is (string= "Twitter bootstrap for weblocks demo" (do-get-text "css=h1"))))) 111 | -------------------------------------------------------------------------------- /tests-app-updates.lisp: -------------------------------------------------------------------------------- 1 | (in-package :weblocks-twitter-bootstrap-application-tests) 2 | 3 | (defvar *test-webapp-prefix* "/bootstrap-app") 4 | 5 | (defstore *bootstrap-tests-store* :memory) 6 | 7 | (defwebapp twitter-bootstrap-sample-app 8 | :prefix *test-webapp-prefix* 9 | :description "Weblocks with twitter bootstrap demo" 10 | :init-user-session 'init-user-session-bootstrap 11 | :subclasses (weblocks-twitter-bootstrap-application:twitter-bootstrap-webapp) 12 | :autostart t 13 | :ignore-default-dependencies nil 14 | :debug t) 15 | 16 | (defmethod render-page-body :after ((app twitter-bootstrap-sample-app) body-string) 17 | (weblocks-selenium-tests-app::render-apps-list)) 18 | 19 | (define-demo-action 20 | "Bootstrap theme demos" 21 | (lambda (&rest args) 22 | (redirect *test-webapp-prefix* :defer nil)) 23 | :prototype-engine-p nil) 24 | 25 | (defvar *demo-actions* nil) 26 | 27 | (defun define-bootstrap-demo-action (link-name action &key (prototype-engine-p t) (jquery-engine-p t)) 28 | "Used to add action to demo list, 29 | :prototype-engine-p and :jquery-engine-p keys 30 | are responsive for displaying action in one or both demo applications" 31 | (push (list link-name action prototype-engine-p jquery-engine-p) *demo-actions*)) 32 | 33 | (define-bootstrap-demo-action "Dialog" #'weblocks-selenium-tests-app::dialog-demonstration-action) 34 | 35 | (defclass test-model () 36 | ((id) 37 | (title :accessor test-model-title :initarg :title) 38 | (content :accessor test-model-content :initarg :content))) 39 | 40 | (defun add-demo-records-to-test-model () 41 | (loop for i from 1 to 5 do 42 | (persist-object 43 | *bootstrap-tests-store* 44 | (make-instance 45 | 'test-model 46 | :title (format nil "Title-~A" i) 47 | :content (format nil "Content-~A" i))))) 48 | 49 | (defun init-user-session-bootstrap (root &optional (add-demo-records t)) 50 | (when add-demo-records 51 | (add-demo-records-to-test-model)) 52 | (setf (widget-children root) 53 | (list (lambda (&rest args) 54 | (with-html 55 | (:h1 "Twitter bootstrap for weblocks demo") 56 | (:ul 57 | (loop for (link-title action) in (reverse *demo-actions*) 58 | do 59 | (cl-who:htm (:li (render-link action link-title)))))))))) 60 | 61 | (defun gridedit-demonstration-action (&rest args) 62 | (let* ((widget)) 63 | (setf widget (make-instance 'gridedit :data-class 'test-model :class-store *bootstrap-tests-store*)) 64 | (do-page 65 | (list 66 | (lambda (&rest args) 67 | (with-html 68 | (:h1 "Gridedit"))) 69 | widget 70 | (lambda (&rest args) 71 | (render-link 72 | (lambda (&rest args) 73 | (init-user-session-bootstrap (root-widget) nil)) 74 | "Back")))))) 75 | 76 | (define-bootstrap-demo-action "Gridedit" #'gridedit-demonstration-action) 77 | (define-bootstrap-demo-action "Choices" 78 | (lambda (&rest args) 79 | (do-choice "Test choice" '((:ok . "Ok") (:great . "Great") (:good . "Good"))))) 80 | 81 | (defun empty-writer (&rest args) 82 | (declare (ignore args))) 83 | 84 | (defun hidden-field-demonstration-action (&rest args) 85 | (do-page 86 | (make-quickform 87 | (defview 88 | nil 89 | (:caption "Form with hidden field" :type form :persistp nil) 90 | (some-field 91 | :present-as hidden 92 | :writer #'empty-writer))))) 93 | 94 | (define-bootstrap-demo-action "Hidden field" #'hidden-field-demonstration-action) 95 | 96 | (defun checkbox-field-demonstration-action (&rest args) 97 | (do-page 98 | (make-quickform 99 | (defview 100 | nil 101 | (:caption "Form with checkbox fields" :type form :persistp nil) 102 | (some-field 103 | :present-as checkbox 104 | :writer #'empty-writer) 105 | (some-other-field 106 | :present-as checkbox 107 | :writer #'empty-writer) 108 | (some-another-field 109 | :present-as checkbox 110 | :writer #'empty-writer))))) 111 | 112 | (define-bootstrap-demo-action "Checkbox fields" #'checkbox-field-demonstration-action) 113 | 114 | (defun navbar-selector-demonstration-action (&rest args) 115 | (let ((widget)) 116 | (setf widget (make-instance 117 | 'composite 118 | :widgets (list 119 | (lambda (&rest args) 120 | (with-html 121 | (:br))) 122 | (make-navbar-selector "test-selector" 123 | (list "First pane" "First tab" nil) 124 | (list "Second pane" "Second tab" "second") 125 | (list "Third pane" "Third tab" "third")) 126 | (lambda (&rest args) 127 | (with-html 128 | (render-link (lambda (&rest args) 129 | (answer widget t)) 130 | "back")))))) 131 | (do-page widget))) 132 | 133 | (define-bootstrap-demo-action "Navbar selector" #'navbar-selector-demonstration-action) 134 | 135 | (defparameter *bootstrap-site-url* "http://localhost:5555/bootstrap-app") 136 | 137 | (defmacro with-new-or-existing-selenium-session-on-bootstrap-site (&body body) 138 | `(let ((*site-url* *bootstrap-site-url*)) 139 | (with-new-or-existing-selenium-session ,@body))) 140 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | Preamble to the Gnu Lesser General Public License 2 | 3 | Copyright (c) 2000 Franz Incorporated, Berkeley, CA 94704 4 | 5 | The concept of the GNU Lesser General Public License version 2.1 6 | ("LGPL") has been adopted to govern the use and distribution of 7 | above-mentioned application. However, the LGPL uses terminology that 8 | is more appropriate for a program written in C than one written in 9 | Lisp. Nevertheless, the LGPL can still be applied to a Lisp program if 10 | certain clarifications are made. This document details those 11 | clarifications. Accordingly, the license for the open-source Lisp 12 | applications consists of this document plus the LGPL. Wherever there 13 | is a conflict between this document and the LGPL, this document takes 14 | precedence over the LGPL. 15 | 16 | A "Library" in Lisp is a collection of Lisp functions, data and 17 | foreign modules. The form of the Library can be Lisp source code (for 18 | processing by an interpreter) or object code (usually the result of 19 | compilation of source code or built with some other 20 | mechanisms). Foreign modules are object code in a form that can be 21 | linked into a Lisp executable. When we speak of functions we do so in 22 | the most general way to include, in addition, methods and unnamed 23 | functions. Lisp "data" is also a general term that includes the data 24 | structures resulting from defining Lisp classes. A Lisp application 25 | may include the same set of Lisp objects as does a Library, but this 26 | does not mean that the application is necessarily a "work based on the 27 | Library" it contains. 28 | 29 | The Library consists of everything in the distribution file set before 30 | any modifications are made to the files. If any of the functions or 31 | classes in the Library are redefined in other files, then those 32 | redefinitions ARE considered a work based on the Library. If 33 | additional methods are added to generic functions in the Library, 34 | those additional methods are NOT considered a work based on the 35 | Library. If Library classes are subclassed, these subclasses are NOT 36 | considered a work based on the Library. If the Library is modified to 37 | explicitly call other functions that are neither part of Lisp itself 38 | nor an available add-on module to Lisp, then the functions called by 39 | the modified Library ARE considered a work based on the Library. The 40 | goal is to ensure that the Library will compile and run without 41 | getting undefined function errors. 42 | 43 | It is permitted to add proprietary source code to the Library, but it 44 | must be done in a way such that the Library will still run without 45 | that proprietary code present. Section 5 of the LGPL distinguishes 46 | between the case of a library being dynamically linked at runtime and 47 | one being statically linked at build time. Section 5 of the LGPL 48 | states that the former results in an executable that is a "work that 49 | uses the Library." Section 5 of the LGPL states that the latter 50 | results in one that is a "derivative of the Library", which is 51 | therefore covered by the LGPL. Since Lisp only offers one choice, 52 | which is to link the Library into an executable at build time, we 53 | declare that, for the purpose applying the LGPL to the Library, an 54 | executable that results from linking a "work that uses the Library" 55 | with the Library is considered a "work that uses the Library" and is 56 | therefore NOT covered by the LGPL. 57 | 58 | Because of this declaration, section 6 of LGPL is not applicable to 59 | the Library. However, in connection with each distribution of this 60 | executable, you must also deliver, in accordance with the terms and 61 | conditions of the LGPL, the source code of Library (or your derivative 62 | thereof) that is incorporated into this executable. 63 | 64 | GNU LESSER GENERAL PUBLIC LICENSE 65 | Version 3, 29 June 2007 66 | 67 | Copyright (C) 2007 Free Software Foundation, Inc. 68 | Everyone is permitted to copy and distribute verbatim copies 69 | of this license document, but changing it is not allowed. 70 | 71 | 72 | This version of the GNU Lesser General Public License incorporates 73 | the terms and conditions of version 3 of the GNU General Public 74 | License, supplemented by the additional permissions listed below. 75 | 76 | 0. Additional Definitions. 77 | 78 | As used herein, "this License" refers to version 3 of the GNU Lesser 79 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 80 | General Public License. 81 | 82 | "The Library" refers to a covered work governed by this License, 83 | other than an Application or a Combined Work as defined below. 84 | 85 | An "Application" is any work that makes use of an interface provided 86 | by the Library, but which is not otherwise based on the Library. 87 | Defining a subclass of a class defined by the Library is deemed a mode 88 | of using an interface provided by the Library. 89 | 90 | A "Combined Work" is a work produced by combining or linking an 91 | Application with the Library. The particular version of the Library 92 | with which the Combined Work was made is also called the "Linked 93 | Version". 94 | 95 | The "Minimal Corresponding Source" for a Combined Work means the 96 | Corresponding Source for the Combined Work, excluding any source code 97 | for portions of the Combined Work that, considered in isolation, are 98 | based on the Application, and not on the Linked Version. 99 | 100 | The "Corresponding Application Code" for a Combined Work means the 101 | object code and/or source code for the Application, including any data 102 | and utility programs needed for reproducing the Combined Work from the 103 | Application, but excluding the System Libraries of the Combined Work. 104 | 105 | 1. Exception to Section 3 of the GNU GPL. 106 | 107 | You may convey a covered work under sections 3 and 4 of this License 108 | without being bound by section 3 of the GNU GPL. 109 | 110 | 2. Conveying Modified Versions. 111 | 112 | If you modify a copy of the Library, and, in your modifications, a 113 | facility refers to a function or data to be supplied by an Application 114 | that uses the facility (other than as an argument passed when the 115 | facility is invoked), then you may convey a copy of the modified 116 | version: 117 | 118 | a) under this License, provided that you make a good faith effort to 119 | ensure that, in the event an Application does not supply the 120 | function or data, the facility still operates, and performs 121 | whatever part of its purpose remains meaningful, or 122 | 123 | b) under the GNU GPL, with none of the additional permissions of 124 | this License applicable to that copy. 125 | 126 | 3. Object Code Incorporating Material from Library Header Files. 127 | 128 | The object code form of an Application may incorporate material from 129 | a header file that is part of the Library. You may convey such object 130 | code under terms of your choice, provided that, if the incorporated 131 | material is not limited to numerical parameters, data structure 132 | layouts and accessors, or small macros, inline functions and templates 133 | (ten or fewer lines in length), you do both of the following: 134 | 135 | a) Give prominent notice with each copy of the object code that the 136 | Library is used in it and that the Library and its use are 137 | covered by this License. 138 | 139 | b) Accompany the object code with a copy of the GNU GPL and this license 140 | document. 141 | 142 | 4. Combined Works. 143 | 144 | You may convey a Combined Work under terms of your choice that, 145 | taken together, effectively do not restrict modification of the 146 | portions of the Library contained in the Combined Work and reverse 147 | engineering for debugging such modifications, if you also do each of 148 | the following: 149 | 150 | a) Give prominent notice with each copy of the Combined Work that 151 | the Library is used in it and that the Library and its use are 152 | covered by this License. 153 | 154 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 155 | document. 156 | 157 | c) For a Combined Work that displays copyright notices during 158 | execution, include the copyright notice for the Library among 159 | these notices, as well as a reference directing the user to the 160 | copies of the GNU GPL and this license document. 161 | 162 | d) Do one of the following: 163 | 164 | 0) Convey the Minimal Corresponding Source under the terms of this 165 | License, and the Corresponding Application Code in a form 166 | suitable for, and under terms that permit, the user to 167 | recombine or relink the Application with a modified version of 168 | the Linked Version to produce a modified Combined Work, in the 169 | manner specified by section 6 of the GNU GPL for conveying 170 | Corresponding Source. 171 | 172 | 1) Use a suitable shared library mechanism for linking with the 173 | Library. A suitable mechanism is one that (a) uses at run time 174 | a copy of the Library already present on the user's computer 175 | system, and (b) will operate properly with a modified version 176 | of the Library that is interface-compatible with the Linked 177 | Version. 178 | 179 | e) Provide Installation Information, but only if you would otherwise 180 | be required to provide such information under section 6 of the 181 | GNU GPL, and only to the extent that such information is 182 | necessary to install and execute a modified version of the 183 | Combined Work produced by recombining or relinking the 184 | Application with a modified version of the Linked Version. (If 185 | you use option 4d0, the Installation Information must accompany 186 | the Minimal Corresponding Source and Corresponding Application 187 | Code. If you use option 4d1, you must provide the Installation 188 | Information in the manner specified by section 6 of the GNU GPL 189 | for conveying Corresponding Source.) 190 | 191 | 5. Combined Libraries. 192 | 193 | You may place library facilities that are a work based on the 194 | Library side by side in a single library together with other library 195 | facilities that are not Applications and are not covered by this 196 | License, and convey such a combined library under terms of your 197 | choice, if you do both of the following: 198 | 199 | a) Accompany the combined library with a copy of the same work based 200 | on the Library, uncombined with any other library facilities, 201 | conveyed under the terms of this License. 202 | 203 | b) Give prominent notice with the combined library that part of it 204 | is a work based on the Library, and explaining where to find the 205 | accompanying uncombined form of the same work. 206 | 207 | 6. Revised Versions of the GNU Lesser General Public License. 208 | 209 | The Free Software Foundation may publish revised and/or new versions 210 | of the GNU Lesser General Public License from time to time. Such new 211 | versions will be similar in spirit to the present version, but may 212 | differ in detail to address new problems or concerns. 213 | 214 | Each version is given a distinguishing version number. If the 215 | Library as you received it specifies that a certain numbered version 216 | of the GNU Lesser General Public License "or any later version" 217 | applies to it, you have the option of following the terms and 218 | conditions either of that published version or of any later version 219 | published by the Free Software Foundation. If the Library as you 220 | received it does not specify a version number of the GNU Lesser 221 | General Public License, you may choose any version of the GNU Lesser 222 | General Public License ever published by the Free Software Foundation. 223 | 224 | If the Library as you received it specifies that a proxy can decide 225 | whether future versions of the GNU Lesser General Public License shall 226 | apply, that proxy's public statement of acceptance of any version is 227 | permanent authorization for you to choose that version for the 228 | Library. 229 | --------------------------------------------------------------------------------