From 40317f9b943c4c23f943191750f064fae2a91e20 Mon Sep 17 00:00:00 2001 From: chriddyp Date: Fri, 23 Feb 2018 16:40:36 -0500 Subject: [PATCH 1/3] integration tests --- circle.yml | 20 +++++++ requirements.txt | 68 +++++++++++++++++++++-- tests/IntegrationTests.py | 77 ++++++++++++++++++++++++++ tests/__init__.py | 0 tests/test_dash_html_components.py | 4 +- tests/test_integration.py | 86 ++++++++++++++++++++++++++++++ tests/utils.py | 22 ++++++++ tox.ini | 14 +++++ 8 files changed, 286 insertions(+), 5 deletions(-) create mode 100644 circle.yml create mode 100644 tests/IntegrationTests.py create mode 100644 tests/__init__.py create mode 100644 tests/test_integration.py create mode 100644 tests/utils.py create mode 100644 tox.ini diff --git a/circle.yml b/circle.yml new file mode 100644 index 00000000..eea850f7 --- /dev/null +++ b/circle.yml @@ -0,0 +1,20 @@ +machine: + node: + version: 6.9.2 + post: + - pyenv global 2.7.10 + environment: + TOX_PYTHON_27: python2.7 + +dependencies: + pre: + - npm install -g eslint + - pip install tox + - npm install + - node_modules/.bin/builder run build-dist + - node_modules/.bin/builder run copy-lib + +test: + override: + - tox + - npm run test diff --git a/requirements.txt b/requirements.txt index cd8c47d3..5a98d1d8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,65 @@ ---index-url https://pypi.python.org/simple/ - --e . +appnope==0.1.0 +asn1crypto==0.22.0 +backports.shutil-get-terminal-size==1.0.0 +certifi==2017.7.27.1 +cffi==1.10.0 +chardet==3.0.4 +click==6.7 +cryptography==2.0.3 +dash==0.20.0 +dash-core-components==0.18.1 +dash-renderer +decorator==4.1.2 +enum34==1.1.6 +Flask==0.12.2 +Flask-Compress==1.4.0 +Flask-SeaSurf==0.2.2 +funcsigs==1.0.2 +functools32==3.2.3.post2 +idna==2.6 +ipaddress==1.0.18 +ipdb==0.10.3 +ipython==5.4.1 +ipython-genutils==0.2.0 +itsdangerous==0.24 +Jinja2==2.9.6 +jsonschema==2.6.0 +jupyter-core==4.3.0 +loremipsum==1.0.5 +MarkupSafe==1.0 +mock==2.0.0 +nbformat==4.4.0 +numpy==1.13.1 +pandas==0.20.3 +pathlib2==2.3.0 +pbr==3.1.1 +percy==1.0.6 +pexpect==4.2.1 +pickleshare==0.7.4 +pkginfo==1.4.1 +plotly==2.0.15 +pluggy==0.5.2 +prompt-toolkit==1.0.15 +ptyprocess==0.5.2 +py==1.4.34 +pycparser==2.18 +Pygments==2.2.0 +pyOpenSSL==17.2.0 +python-dateutil==2.6.1 +pytz==2017.2 +requests==2.18.4 +requests-toolbelt==0.8.0 +scandir==1.5 +selenium==3.5.0 +simplegeneric==0.8.1 +six==1.10.0 +tox==2.8.2 +tox-pyenv==1.1.0 +tqdm==4.15.0 +traitlets==4.3.2 +twine==1.9.1 +urllib3==1.22 +virtualenv==15.1.0 +wcwidth==0.1.7 +Werkzeug==0.12.2 +xlrd==1.1.0 diff --git a/tests/IntegrationTests.py b/tests/IntegrationTests.py new file mode 100644 index 00000000..ef8270cd --- /dev/null +++ b/tests/IntegrationTests.py @@ -0,0 +1,77 @@ +from __future__ import absolute_import +import multiprocessing +import time +import unittest +import percy +from selenium import webdriver + + +class IntegrationTests(unittest.TestCase): + + @classmethod + def setUpClass(cls): + super(IntegrationTests, cls).setUpClass() + + cls.driver = webdriver.Chrome() + loader = percy.ResourceLoader(webdriver=cls.driver) + cls.percy_runner = percy.Runner(loader=loader) + cls.percy_runner.initialize_build() + + @classmethod + def tearDownClass(cls): + super(IntegrationTests, cls).tearDownClass() + cls.driver.quit() + cls.percy_runner.finalize_build() + + def setUp(self): + pass + + def tearDown(self): + time.sleep(3) + self.server_process.terminate() + time.sleep(3) + + def startServer(self, app): + def run(): + app.scripts.config.serve_locally = True + app.css.config.serve_locally = True + app.run_server( + port=8050, + debug=False, + processes=4 + ) + + # Run on a separate process so that it doesn't block + self.server_process = multiprocessing.Process(target=run) + self.server_process.start() + time.sleep(5) + + # Visit the dash page + self.driver.get('http://localhost:8050') + time.sleep(0.5) + + # Inject an error and warning logger + logger = ''' + window.tests = {}; + window.tests.console = {error: [], warn: [], log: []}; + + var _log = console.log; + var _warn = console.warn; + var _error = console.error; + + console.log = function() { + window.tests.console.log.push({method: 'log', arguments: arguments}); + return _log.apply(console, arguments); + }; + + console.warn = function() { + window.tests.console.warn.push({method: 'warn', arguments: arguments}); + return _warn.apply(console, arguments); + }; + + console.error = function() { + window.tests.console.error.push({method: 'error', arguments: arguments}); + return _error.apply(console, arguments); + }; + ''' + self.driver.execute_script(logger) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_dash_html_components.py b/tests/test_dash_html_components.py index f6052300..50dc13b6 100644 --- a/tests/test_dash_html_components.py +++ b/tests/test_dash_html_components.py @@ -9,8 +9,8 @@ def test_imports(self): lambda s: s[0].upper() + s[1:], f.read().split('\n') ) - elements += ['MapEl', 'ObjectEl', 'component'] - for s in ['Slot', 'Map', 'Object']: + elements += ['MapEl', 'ObjectEl', 'component', 'version'] + for s in ['Map', 'Object']: elements.remove(s) self.assertEqual( diff --git a/tests/test_integration.py b/tests/test_integration.py new file mode 100644 index 00000000..ef8abdd3 --- /dev/null +++ b/tests/test_integration.py @@ -0,0 +1,86 @@ +import base64 +from datetime import datetime +import io +import itertools +from multiprocessing import Value +import os +import pandas as pd +from selenium import webdriver +from selenium.webdriver.common.keys import Keys +import sys +from textwrap import dedent +import time +try: + from urlparse import urlparse +except ImportError: + from urllib.parse import urlparse + +import dash +from dash.dependencies import Input, Output, State +import dash_html_components as html +import dash_core_components as dcc + +from .IntegrationTests import IntegrationTests +from .utils import assert_clean_console + + +class Tests(IntegrationTests): + def setUp(self): + pass + + def wait_for_element_by_css_selector(self, selector): + start_time = time.time() + while time.time() < start_time + 20: + try: + return self.driver.find_element_by_css_selector(selector) + except Exception as e: + pass + time.sleep(0.25) + raise e + + def wait_for_text_to_equal(self, selector, assertion_text): + start_time = time.time() + while time.time() < start_time + 20: + el = self.wait_for_element_by_css_selector(selector) + try: + return self.assertEqual(el.text, assertion_text) + except Exception as e: + pass + time.sleep(0.25) + raise e + + def snapshot(self, name): + if 'PERCY_PROJECT' in os.environ and 'PERCY_TOKEN' in os.environ: + python_version = sys.version.split(' ')[0] + print('Percy Snapshot {}'.format(python_version)) + self.percy_runner.snapshot(name=name) + + def test_click(self): + app = dash.Dash() + app.layout = html.Div([ + html.Div(id='container'), + html.Button('Click', id='button', n_clicks=0) + ]) + + call_count = Value('i', 0) + + @app.callback(Output('container', 'children'), [Input('button', 'n_clicks')]) + def update_output(n_clicks): + call_count.value += 1 + return 'You have clicked the button {} times'.format(n_clicks) + + self.startServer(app) + + self.wait_for_element_by_css_selector('#container') + + self.wait_for_text_to_equal( + '#container', 'You have clicked the button 0 times') + self.assertEqual(call_count.value, 1) + self.snapshot('button initialization') + + self.driver.find_element_by_css_selector('#button').click() + + self.wait_for_text_to_equal( + '#container', 'You have clicked the button 1 times') + self.assertEqual(call_count.value, 2) + self.snapshot('button click') diff --git a/tests/utils.py b/tests/utils.py new file mode 100644 index 00000000..349264fd --- /dev/null +++ b/tests/utils.py @@ -0,0 +1,22 @@ +import time + + +def assert_clean_console(TestClass): + def assert_no_console_errors(TestClass): + TestClass.assertEqual( + TestClass.driver.execute_script( + 'return window.tests.console.error.length' + ), + 0 + ) + + def assert_no_console_warnings(TestClass): + TestClass.assertEqual( + TestClass.driver.execute_script( + 'return window.tests.console.warn.length' + ), + 0 + ) + + assert_no_console_warnings(TestClass) + assert_no_console_errors(TestClass) diff --git a/tox.ini b/tox.ini new file mode 100644 index 00000000..73b00ce3 --- /dev/null +++ b/tox.ini @@ -0,0 +1,14 @@ +[tox] +envlist = py27 + +[testenv] +deps = -rrequirements.txt +# Variables for chrome and selenium +# See https://bugs.launchpad.net/horizon/+bug/1684321 +passenv = * +[testenv:py27] +basepython={env:TOX_PYTHON_27} +commands = + python --version + python -m unittest tests.test_dash_html_components + python -m unittest tests.test_integration From 2b71f6d5a5bf756fd5ec037b90204d4af417a205 Mon Sep 17 00:00:00 2001 From: chriddyp Date: Fri, 23 Feb 2018 16:40:51 -0500 Subject: [PATCH 2/3] rerun publish --- lib/metadata.json | 746 ++++++++++++++++-- scripts/data/attributes.json | 2 + scripts/data/elements.txt | 19 +- src/components/Audio.react.js | 5 + src/components/Bgsound.react.js | 131 +++ .../{Base.react.js => Image.react.js} | 26 +- src/components/Nobr.react.js | 126 +++ src/components/Noframes.react.js | 126 +++ src/components/Picture.react.js | 126 +++ src/index.js | 8 +- 10 files changed, 1207 insertions(+), 108 deletions(-) create mode 100644 src/components/Bgsound.react.js rename src/components/{Base.react.js => Image.react.js} (90%) create mode 100644 src/components/Nobr.react.js create mode 100644 src/components/Noframes.react.js create mode 100644 src/components/Picture.react.js diff --git a/lib/metadata.json b/lib/metadata.json index 60afec4a..2b826126 100644 --- a/lib/metadata.json +++ b/lib/metadata.json @@ -1327,6 +1327,13 @@ "required": false, "description": "Indicates whether the media should start playing from the start when it's finished." }, + "muted": { + "type": { + "name": "string" + }, + "required": false, + "description": "Indicates whether the audio will be initially silenced on page load." + }, "preload": { "type": { "name": "string" @@ -1590,7 +1597,7 @@ } } }, - "src/components/Base.react.js": { + "src/components/Basefont.react.js": { "description": "", "methods": [], "props": { @@ -1627,20 +1634,6 @@ "required": false, "description": "A unique identifier for the component, used to improve\nperformance by React.js while rendering components\nSee https://reactjs.org/docs/lists-and-keys.html for more info" }, - "href": { - "type": { - "name": "string" - }, - "required": false, - "description": "The URL of a linked resource." - }, - "target": { - "type": { - "name": "string" - }, - "required": false, - "description": "" - }, "accessKey": { "type": { "name": "string" @@ -1747,7 +1740,7 @@ } } }, - "src/components/Basefont.react.js": { + "src/components/Bdi.react.js": { "description": "", "methods": [], "props": { @@ -1890,7 +1883,7 @@ } } }, - "src/components/Bdi.react.js": { + "src/components/Bdo.react.js": { "description": "", "methods": [], "props": { @@ -2033,7 +2026,7 @@ } } }, - "src/components/Bdo.react.js": { + "src/components/Bgsound.react.js": { "description": "", "methods": [], "props": { @@ -2070,6 +2063,13 @@ "required": false, "description": "A unique identifier for the component, used to improve\nperformance by React.js while rendering components\nSee https://reactjs.org/docs/lists-and-keys.html for more info" }, + "loop": { + "type": { + "name": "string" + }, + "required": false, + "description": "Indicates whether the media should start playing from the start when it's finished." + }, "accessKey": { "type": { "name": "string" @@ -9198,6 +9198,149 @@ } } }, + "src/components/Image.react.js": { + "description": "", + "methods": [], + "props": { + "id": { + "type": { + "name": "string" + }, + "required": false, + "description": "The ID of this component, used to identify dash components\nin callbacks. The ID needs to be unique across all of the\ncomponents in an app." + }, + "children": { + "type": { + "name": "node" + }, + "required": false, + "description": "The children of this component" + }, + "n_clicks": { + "type": { + "name": "custom", + "raw": "PropTypes.integer" + }, + "required": false, + "description": "An integer that represents the number of times\nthat this element has been clicked on.", + "defaultValue": { + "value": "0", + "computed": false + } + }, + "key": { + "type": { + "name": "string" + }, + "required": false, + "description": "A unique identifier for the component, used to improve\nperformance by React.js while rendering components\nSee https://reactjs.org/docs/lists-and-keys.html for more info" + }, + "accessKey": { + "type": { + "name": "string" + }, + "required": false, + "description": "Defines a keyboard shortcut to activate or add focus to the element." + }, + "className": { + "type": { + "name": "string" + }, + "required": false, + "description": "Often used with CSS to style elements with common properties." + }, + "contentEditable": { + "type": { + "name": "string" + }, + "required": false, + "description": "Indicates whether the element's content is editable." + }, + "contextMenu": { + "type": { + "name": "string" + }, + "required": false, + "description": "Defines the ID of a element which will serve as the element's context menu." + }, + "dir": { + "type": { + "name": "string" + }, + "required": false, + "description": "Defines the text direction. Allowed values are ltr (Left-To-Right) or rtl (Right-To-Left)" + }, + "draggable": { + "type": { + "name": "string" + }, + "required": false, + "description": "Defines whether the element can be dragged." + }, + "hidden": { + "type": { + "name": "string" + }, + "required": false, + "description": "Prevents rendering of given element, while keeping child elements, e.g. script elements, active." + }, + "lang": { + "type": { + "name": "string" + }, + "required": false, + "description": "Defines the language used in the element." + }, + "spellCheck": { + "type": { + "name": "string" + }, + "required": false, + "description": "Indicates whether spell checking is allowed for the element." + }, + "style": { + "type": { + "name": "object" + }, + "required": false, + "description": "Defines CSS styles which will override styles previously set." + }, + "tabIndex": { + "type": { + "name": "string" + }, + "required": false, + "description": "Overrides the browser's default tab order and follows the one specified instead." + }, + "title": { + "type": { + "name": "string" + }, + "required": false, + "description": "Text to be displayed in a tooltip when hovering over the element." + }, + "fireEvent": { + "type": { + "name": "func" + }, + "required": false, + "description": "A callback for firing events to dash." + }, + "dashEvents": { + "type": { + "name": "enum", + "value": [ + { + "value": "'click'", + "computed": false + } + ] + }, + "required": false, + "description": "" + } + } + }, "src/components/Img.react.js": { "description": "", "methods": [], @@ -12481,7 +12624,7 @@ } } }, - "src/components/Noembed.react.js": { + "src/components/Nobr.react.js": { "description": "", "methods": [], "props": { @@ -12624,7 +12767,7 @@ } } }, - "src/components/Noscript.react.js": { + "src/components/Noembed.react.js": { "description": "", "methods": [], "props": { @@ -12767,7 +12910,7 @@ } } }, - "src/components/ObjectEl.react.js": { + "src/components/Noframes.react.js": { "description": "", "methods": [], "props": { @@ -12804,48 +12947,6 @@ "required": false, "description": "A unique identifier for the component, used to improve\nperformance by React.js while rendering components\nSee https://reactjs.org/docs/lists-and-keys.html for more info" }, - "form": { - "type": { - "name": "string" - }, - "required": false, - "description": "Indicates the form that is the owner of the element." - }, - "height": { - "type": { - "name": "string" - }, - "required": false, - "description": "Specifies the height of elements listed here. For all other elements, use the CSS height property. Note: In some instances, such as
, this is a legacy attribute, in which case the CSS height property should be used instead." - }, - "name": { - "type": { - "name": "string" - }, - "required": false, - "description": "Name of the element. For example used by the server to identify the fields in form submits." - }, - "type": { - "type": { - "name": "string" - }, - "required": false, - "description": "Defines the type of the element." - }, - "useMap": { - "type": { - "name": "string" - }, - "required": false, - "description": "" - }, - "width": { - "type": { - "name": "string" - }, - "required": false, - "description": "For the elements listed here, this establishes the element's width. Note: For all other instances, such as
, this is a legacy attribute, in which case the CSS width property should be used instead." - }, "accessKey": { "type": { "name": "string" @@ -12952,7 +13053,7 @@ } } }, - "src/components/Ol.react.js": { + "src/components/Noscript.react.js": { "description": "", "methods": [], "props": { @@ -12989,20 +13090,6 @@ "required": false, "description": "A unique identifier for the component, used to improve\nperformance by React.js while rendering components\nSee https://reactjs.org/docs/lists-and-keys.html for more info" }, - "reversed": { - "type": { - "name": "string" - }, - "required": false, - "description": "Indicates whether the list should be displayed in a descending order instead of a ascending." - }, - "start": { - "type": { - "name": "string" - }, - "required": false, - "description": "Defines the first number if other than 1." - }, "accessKey": { "type": { "name": "string" @@ -13109,7 +13196,7 @@ } } }, - "src/components/Optgroup.react.js": { + "src/components/ObjectEl.react.js": { "description": "", "methods": [], "props": { @@ -13146,33 +13233,375 @@ "required": false, "description": "A unique identifier for the component, used to improve\nperformance by React.js while rendering components\nSee https://reactjs.org/docs/lists-and-keys.html for more info" }, - "disabled": { + "form": { "type": { "name": "string" }, "required": false, - "description": "Indicates whether the user can interact with the element." + "description": "Indicates the form that is the owner of the element." }, - "accessKey": { + "height": { "type": { "name": "string" }, "required": false, - "description": "Defines a keyboard shortcut to activate or add focus to the element." + "description": "Specifies the height of elements listed here. For all other elements, use the CSS height property. Note: In some instances, such as
, this is a legacy attribute, in which case the CSS height property should be used instead." }, - "className": { + "name": { "type": { "name": "string" }, "required": false, - "description": "Often used with CSS to style elements with common properties." + "description": "Name of the element. For example used by the server to identify the fields in form submits." }, - "contentEditable": { + "type": { "type": { "name": "string" }, "required": false, - "description": "Indicates whether the element's content is editable." + "description": "Defines the type of the element." + }, + "useMap": { + "type": { + "name": "string" + }, + "required": false, + "description": "" + }, + "width": { + "type": { + "name": "string" + }, + "required": false, + "description": "For the elements listed here, this establishes the element's width. Note: For all other instances, such as
, this is a legacy attribute, in which case the CSS width property should be used instead." + }, + "accessKey": { + "type": { + "name": "string" + }, + "required": false, + "description": "Defines a keyboard shortcut to activate or add focus to the element." + }, + "className": { + "type": { + "name": "string" + }, + "required": false, + "description": "Often used with CSS to style elements with common properties." + }, + "contentEditable": { + "type": { + "name": "string" + }, + "required": false, + "description": "Indicates whether the element's content is editable." + }, + "contextMenu": { + "type": { + "name": "string" + }, + "required": false, + "description": "Defines the ID of a element which will serve as the element's context menu." + }, + "dir": { + "type": { + "name": "string" + }, + "required": false, + "description": "Defines the text direction. Allowed values are ltr (Left-To-Right) or rtl (Right-To-Left)" + }, + "draggable": { + "type": { + "name": "string" + }, + "required": false, + "description": "Defines whether the element can be dragged." + }, + "hidden": { + "type": { + "name": "string" + }, + "required": false, + "description": "Prevents rendering of given element, while keeping child elements, e.g. script elements, active." + }, + "lang": { + "type": { + "name": "string" + }, + "required": false, + "description": "Defines the language used in the element." + }, + "spellCheck": { + "type": { + "name": "string" + }, + "required": false, + "description": "Indicates whether spell checking is allowed for the element." + }, + "style": { + "type": { + "name": "object" + }, + "required": false, + "description": "Defines CSS styles which will override styles previously set." + }, + "tabIndex": { + "type": { + "name": "string" + }, + "required": false, + "description": "Overrides the browser's default tab order and follows the one specified instead." + }, + "title": { + "type": { + "name": "string" + }, + "required": false, + "description": "Text to be displayed in a tooltip when hovering over the element." + }, + "fireEvent": { + "type": { + "name": "func" + }, + "required": false, + "description": "A callback for firing events to dash." + }, + "dashEvents": { + "type": { + "name": "enum", + "value": [ + { + "value": "'click'", + "computed": false + } + ] + }, + "required": false, + "description": "" + } + } + }, + "src/components/Ol.react.js": { + "description": "", + "methods": [], + "props": { + "id": { + "type": { + "name": "string" + }, + "required": false, + "description": "The ID of this component, used to identify dash components\nin callbacks. The ID needs to be unique across all of the\ncomponents in an app." + }, + "children": { + "type": { + "name": "node" + }, + "required": false, + "description": "The children of this component" + }, + "n_clicks": { + "type": { + "name": "custom", + "raw": "PropTypes.integer" + }, + "required": false, + "description": "An integer that represents the number of times\nthat this element has been clicked on.", + "defaultValue": { + "value": "0", + "computed": false + } + }, + "key": { + "type": { + "name": "string" + }, + "required": false, + "description": "A unique identifier for the component, used to improve\nperformance by React.js while rendering components\nSee https://reactjs.org/docs/lists-and-keys.html for more info" + }, + "reversed": { + "type": { + "name": "string" + }, + "required": false, + "description": "Indicates whether the list should be displayed in a descending order instead of a ascending." + }, + "start": { + "type": { + "name": "string" + }, + "required": false, + "description": "Defines the first number if other than 1." + }, + "accessKey": { + "type": { + "name": "string" + }, + "required": false, + "description": "Defines a keyboard shortcut to activate or add focus to the element." + }, + "className": { + "type": { + "name": "string" + }, + "required": false, + "description": "Often used with CSS to style elements with common properties." + }, + "contentEditable": { + "type": { + "name": "string" + }, + "required": false, + "description": "Indicates whether the element's content is editable." + }, + "contextMenu": { + "type": { + "name": "string" + }, + "required": false, + "description": "Defines the ID of a element which will serve as the element's context menu." + }, + "dir": { + "type": { + "name": "string" + }, + "required": false, + "description": "Defines the text direction. Allowed values are ltr (Left-To-Right) or rtl (Right-To-Left)" + }, + "draggable": { + "type": { + "name": "string" + }, + "required": false, + "description": "Defines whether the element can be dragged." + }, + "hidden": { + "type": { + "name": "string" + }, + "required": false, + "description": "Prevents rendering of given element, while keeping child elements, e.g. script elements, active." + }, + "lang": { + "type": { + "name": "string" + }, + "required": false, + "description": "Defines the language used in the element." + }, + "spellCheck": { + "type": { + "name": "string" + }, + "required": false, + "description": "Indicates whether spell checking is allowed for the element." + }, + "style": { + "type": { + "name": "object" + }, + "required": false, + "description": "Defines CSS styles which will override styles previously set." + }, + "tabIndex": { + "type": { + "name": "string" + }, + "required": false, + "description": "Overrides the browser's default tab order and follows the one specified instead." + }, + "title": { + "type": { + "name": "string" + }, + "required": false, + "description": "Text to be displayed in a tooltip when hovering over the element." + }, + "fireEvent": { + "type": { + "name": "func" + }, + "required": false, + "description": "A callback for firing events to dash." + }, + "dashEvents": { + "type": { + "name": "enum", + "value": [ + { + "value": "'click'", + "computed": false + } + ] + }, + "required": false, + "description": "" + } + } + }, + "src/components/Optgroup.react.js": { + "description": "", + "methods": [], + "props": { + "id": { + "type": { + "name": "string" + }, + "required": false, + "description": "The ID of this component, used to identify dash components\nin callbacks. The ID needs to be unique across all of the\ncomponents in an app." + }, + "children": { + "type": { + "name": "node" + }, + "required": false, + "description": "The children of this component" + }, + "n_clicks": { + "type": { + "name": "custom", + "raw": "PropTypes.integer" + }, + "required": false, + "description": "An integer that represents the number of times\nthat this element has been clicked on.", + "defaultValue": { + "value": "0", + "computed": false + } + }, + "key": { + "type": { + "name": "string" + }, + "required": false, + "description": "A unique identifier for the component, used to improve\nperformance by React.js while rendering components\nSee https://reactjs.org/docs/lists-and-keys.html for more info" + }, + "disabled": { + "type": { + "name": "string" + }, + "required": false, + "description": "Indicates whether the user can interact with the element." + }, + "accessKey": { + "type": { + "name": "string" + }, + "required": false, + "description": "Defines a keyboard shortcut to activate or add focus to the element." + }, + "className": { + "type": { + "name": "string" + }, + "required": false, + "description": "Often used with CSS to style elements with common properties." + }, + "contentEditable": { + "type": { + "name": "string" + }, + "required": false, + "description": "Indicates whether the element's content is editable." }, "contextMenu": { "type": { @@ -13887,6 +14316,149 @@ } } }, + "src/components/Picture.react.js": { + "description": "", + "methods": [], + "props": { + "id": { + "type": { + "name": "string" + }, + "required": false, + "description": "The ID of this component, used to identify dash components\nin callbacks. The ID needs to be unique across all of the\ncomponents in an app." + }, + "children": { + "type": { + "name": "node" + }, + "required": false, + "description": "The children of this component" + }, + "n_clicks": { + "type": { + "name": "custom", + "raw": "PropTypes.integer" + }, + "required": false, + "description": "An integer that represents the number of times\nthat this element has been clicked on.", + "defaultValue": { + "value": "0", + "computed": false + } + }, + "key": { + "type": { + "name": "string" + }, + "required": false, + "description": "A unique identifier for the component, used to improve\nperformance by React.js while rendering components\nSee https://reactjs.org/docs/lists-and-keys.html for more info" + }, + "accessKey": { + "type": { + "name": "string" + }, + "required": false, + "description": "Defines a keyboard shortcut to activate or add focus to the element." + }, + "className": { + "type": { + "name": "string" + }, + "required": false, + "description": "Often used with CSS to style elements with common properties." + }, + "contentEditable": { + "type": { + "name": "string" + }, + "required": false, + "description": "Indicates whether the element's content is editable." + }, + "contextMenu": { + "type": { + "name": "string" + }, + "required": false, + "description": "Defines the ID of a element which will serve as the element's context menu." + }, + "dir": { + "type": { + "name": "string" + }, + "required": false, + "description": "Defines the text direction. Allowed values are ltr (Left-To-Right) or rtl (Right-To-Left)" + }, + "draggable": { + "type": { + "name": "string" + }, + "required": false, + "description": "Defines whether the element can be dragged." + }, + "hidden": { + "type": { + "name": "string" + }, + "required": false, + "description": "Prevents rendering of given element, while keeping child elements, e.g. script elements, active." + }, + "lang": { + "type": { + "name": "string" + }, + "required": false, + "description": "Defines the language used in the element." + }, + "spellCheck": { + "type": { + "name": "string" + }, + "required": false, + "description": "Indicates whether spell checking is allowed for the element." + }, + "style": { + "type": { + "name": "object" + }, + "required": false, + "description": "Defines CSS styles which will override styles previously set." + }, + "tabIndex": { + "type": { + "name": "string" + }, + "required": false, + "description": "Overrides the browser's default tab order and follows the one specified instead." + }, + "title": { + "type": { + "name": "string" + }, + "required": false, + "description": "Text to be displayed in a tooltip when hovering over the element." + }, + "fireEvent": { + "type": { + "name": "func" + }, + "required": false, + "description": "A callback for firing events to dash." + }, + "dashEvents": { + "type": { + "name": "enum", + "value": [ + { + "value": "'click'", + "computed": false + } + ] + }, + "required": false, + "description": "" + } + } + }, "src/components/Plaintext.react.js": { "description": "", "methods": [], diff --git a/scripts/data/attributes.json b/scripts/data/attributes.json index f27df9e0..5e8b8d97 100644 --- a/scripts/data/attributes.json +++ b/scripts/data/attributes.json @@ -420,6 +420,7 @@ }, "muted": { "elements": [ + "audio", "video" ], "description": "Indicates whether the audio will be initially silenced on page load." @@ -863,6 +864,7 @@ "controls", "crossOrigin", "loop", + "muted", "preload", "src" ], diff --git a/scripts/data/elements.txt b/scripts/data/elements.txt index d9144eb2..fd6582b9 100644 --- a/scripts/data/elements.txt +++ b/scripts/data/elements.txt @@ -1,4 +1,3 @@ -base link meta title @@ -7,11 +6,18 @@ article aside footer header +h1 +h2 +h3 +h4 +h5 +h6 hgroup nav section blockquote dd +dir div dl dt @@ -38,6 +44,7 @@ em i kbd mark +nobr q rp rt @@ -51,6 +58,7 @@ strong sub sup time +tt u var wbr @@ -60,9 +68,12 @@ img map track video +applet embed +noembed object param +picture source canvas noscript @@ -105,6 +116,7 @@ template acronym applet basefont +bgsound big blink center @@ -115,13 +127,18 @@ element font frame frameset +image isindex keygen listing marquee +menu +menuitem multicol nextid +nobr noembed +noframes plaintext shadow spacer diff --git a/src/components/Audio.react.js b/src/components/Audio.react.js index 150d1806..d43eca61 100644 --- a/src/components/Audio.react.js +++ b/src/components/Audio.react.js @@ -74,6 +74,11 @@ Audio.propTypes = { */ 'loop': PropTypes.string, + /** + * Indicates whether the audio will be initially silenced on page load. + */ + 'muted': PropTypes.string, + /** * Indicates whether the whole resource, parts of it or nothing should be preloaded. */ diff --git a/src/components/Bgsound.react.js b/src/components/Bgsound.react.js new file mode 100644 index 00000000..cc420e2a --- /dev/null +++ b/src/components/Bgsound.react.js @@ -0,0 +1,131 @@ + +import React, {PropTypes} from 'react'; + +const Bgsound = (props) => { + if (props.fireEvent || props.setProps) { + return ( + { + if (props.setProps) props.setProps({n_clicks: props.n_clicks + 1}); + if (props.fireEvent) props.fireEvent({event: 'click'}); + }} + {...props} + > + {props.children} + + ); + } else { + return ( + + {props.children} + + ); + } +}; + +Bgsound.defaultProps = { + n_clicks: 0 +}; + +Bgsound.propTypes = { + /** + * The ID of this component, used to identify dash components + * in callbacks. The ID needs to be unique across all of the + * components in an app. + */ + 'id': PropTypes.string, + + /** + * The children of this component + */ + 'children': PropTypes.node, + + /** + * An integer that represents the number of times + * that this element has been clicked on. + */ + 'n_clicks': PropTypes.integer, + + /** + * A unique identifier for the component, used to improve + * performance by React.js while rendering components + * See https://reactjs.org/docs/lists-and-keys.html for more info + */ + 'key': PropTypes.string, + + + /** + * Indicates whether the media should start playing from the start when it's finished. + */ + 'loop': PropTypes.string, + + /** + * Defines a keyboard shortcut to activate or add focus to the element. + */ + 'accessKey': PropTypes.string, + + /** + * Often used with CSS to style elements with common properties. + */ + 'className': PropTypes.string, + + /** + * Indicates whether the element's content is editable. + */ + 'contentEditable': PropTypes.string, + + /** + * Defines the ID of a element which will serve as the element's context menu. + */ + 'contextMenu': PropTypes.string, + + /** + * Defines the text direction. Allowed values are ltr (Left-To-Right) or rtl (Right-To-Left) + */ + 'dir': PropTypes.string, + + /** + * Defines whether the element can be dragged. + */ + 'draggable': PropTypes.string, + + /** + * Prevents rendering of given element, while keeping child elements, e.g. script elements, active. + */ + 'hidden': PropTypes.string, + + /** + * Defines the language used in the element. + */ + 'lang': PropTypes.string, + + /** + * Indicates whether spell checking is allowed for the element. + */ + 'spellCheck': PropTypes.string, + + /** + * Defines CSS styles which will override styles previously set. + */ + 'style': PropTypes.object, + + /** + * Overrides the browser's default tab order and follows the one specified instead. + */ + 'tabIndex': PropTypes.string, + + /** + * Text to be displayed in a tooltip when hovering over the element. + */ + 'title': PropTypes.string, + + /** + * A callback for firing events to dash. + */ + 'fireEvent': PropTypes.func, + + 'dashEvents': PropTypes.oneOf(['click']) + +}; + +export default Bgsound; diff --git a/src/components/Base.react.js b/src/components/Image.react.js similarity index 90% rename from src/components/Base.react.js rename to src/components/Image.react.js index 0116d259..c454f4b4 100644 --- a/src/components/Base.react.js +++ b/src/components/Image.react.js @@ -1,10 +1,10 @@ import React, {PropTypes} from 'react'; -const Base = (props) => { +const Image = (props) => { if (props.fireEvent || props.setProps) { return ( - { if (props.setProps) props.setProps({n_clicks: props.n_clicks + 1}); if (props.fireEvent) props.fireEvent({event: 'click'}); @@ -12,22 +12,22 @@ const Base = (props) => { {...props} > {props.children} - + ); } else { return ( - + {props.children} - + ); } }; -Base.defaultProps = { +Image.defaultProps = { n_clicks: 0 }; -Base.propTypes = { +Image.propTypes = { /** * The ID of this component, used to identify dash components * in callbacks. The ID needs to be unique across all of the @@ -54,16 +54,6 @@ Base.propTypes = { 'key': PropTypes.string, - /** - * The URL of a linked resource. - */ - 'href': PropTypes.string, - - /** - * - */ - 'target': PropTypes.string, - /** * Defines a keyboard shortcut to activate or add focus to the element. */ @@ -133,4 +123,4 @@ Base.propTypes = { }; -export default Base; +export default Image; diff --git a/src/components/Nobr.react.js b/src/components/Nobr.react.js new file mode 100644 index 00000000..efbff223 --- /dev/null +++ b/src/components/Nobr.react.js @@ -0,0 +1,126 @@ + +import React, {PropTypes} from 'react'; + +const Nobr = (props) => { + if (props.fireEvent || props.setProps) { + return ( + { + if (props.setProps) props.setProps({n_clicks: props.n_clicks + 1}); + if (props.fireEvent) props.fireEvent({event: 'click'}); + }} + {...props} + > + {props.children} + + ); + } else { + return ( + + {props.children} + + ); + } +}; + +Nobr.defaultProps = { + n_clicks: 0 +}; + +Nobr.propTypes = { + /** + * The ID of this component, used to identify dash components + * in callbacks. The ID needs to be unique across all of the + * components in an app. + */ + 'id': PropTypes.string, + + /** + * The children of this component + */ + 'children': PropTypes.node, + + /** + * An integer that represents the number of times + * that this element has been clicked on. + */ + 'n_clicks': PropTypes.integer, + + /** + * A unique identifier for the component, used to improve + * performance by React.js while rendering components + * See https://reactjs.org/docs/lists-and-keys.html for more info + */ + 'key': PropTypes.string, + + + /** + * Defines a keyboard shortcut to activate or add focus to the element. + */ + 'accessKey': PropTypes.string, + + /** + * Often used with CSS to style elements with common properties. + */ + 'className': PropTypes.string, + + /** + * Indicates whether the element's content is editable. + */ + 'contentEditable': PropTypes.string, + + /** + * Defines the ID of a element which will serve as the element's context menu. + */ + 'contextMenu': PropTypes.string, + + /** + * Defines the text direction. Allowed values are ltr (Left-To-Right) or rtl (Right-To-Left) + */ + 'dir': PropTypes.string, + + /** + * Defines whether the element can be dragged. + */ + 'draggable': PropTypes.string, + + /** + * Prevents rendering of given element, while keeping child elements, e.g. script elements, active. + */ + 'hidden': PropTypes.string, + + /** + * Defines the language used in the element. + */ + 'lang': PropTypes.string, + + /** + * Indicates whether spell checking is allowed for the element. + */ + 'spellCheck': PropTypes.string, + + /** + * Defines CSS styles which will override styles previously set. + */ + 'style': PropTypes.object, + + /** + * Overrides the browser's default tab order and follows the one specified instead. + */ + 'tabIndex': PropTypes.string, + + /** + * Text to be displayed in a tooltip when hovering over the element. + */ + 'title': PropTypes.string, + + /** + * A callback for firing events to dash. + */ + 'fireEvent': PropTypes.func, + + 'dashEvents': PropTypes.oneOf(['click']) + +}; + +export default Nobr; diff --git a/src/components/Noframes.react.js b/src/components/Noframes.react.js new file mode 100644 index 00000000..9e81fb38 --- /dev/null +++ b/src/components/Noframes.react.js @@ -0,0 +1,126 @@ + +import React, {PropTypes} from 'react'; + +const Noframes = (props) => { + if (props.fireEvent || props.setProps) { + return ( + { + if (props.setProps) props.setProps({n_clicks: props.n_clicks + 1}); + if (props.fireEvent) props.fireEvent({event: 'click'}); + }} + {...props} + > + {props.children} + + ); + } else { + return ( + + {props.children} + + ); + } +}; + +Noframes.defaultProps = { + n_clicks: 0 +}; + +Noframes.propTypes = { + /** + * The ID of this component, used to identify dash components + * in callbacks. The ID needs to be unique across all of the + * components in an app. + */ + 'id': PropTypes.string, + + /** + * The children of this component + */ + 'children': PropTypes.node, + + /** + * An integer that represents the number of times + * that this element has been clicked on. + */ + 'n_clicks': PropTypes.integer, + + /** + * A unique identifier for the component, used to improve + * performance by React.js while rendering components + * See https://reactjs.org/docs/lists-and-keys.html for more info + */ + 'key': PropTypes.string, + + + /** + * Defines a keyboard shortcut to activate or add focus to the element. + */ + 'accessKey': PropTypes.string, + + /** + * Often used with CSS to style elements with common properties. + */ + 'className': PropTypes.string, + + /** + * Indicates whether the element's content is editable. + */ + 'contentEditable': PropTypes.string, + + /** + * Defines the ID of a element which will serve as the element's context menu. + */ + 'contextMenu': PropTypes.string, + + /** + * Defines the text direction. Allowed values are ltr (Left-To-Right) or rtl (Right-To-Left) + */ + 'dir': PropTypes.string, + + /** + * Defines whether the element can be dragged. + */ + 'draggable': PropTypes.string, + + /** + * Prevents rendering of given element, while keeping child elements, e.g. script elements, active. + */ + 'hidden': PropTypes.string, + + /** + * Defines the language used in the element. + */ + 'lang': PropTypes.string, + + /** + * Indicates whether spell checking is allowed for the element. + */ + 'spellCheck': PropTypes.string, + + /** + * Defines CSS styles which will override styles previously set. + */ + 'style': PropTypes.object, + + /** + * Overrides the browser's default tab order and follows the one specified instead. + */ + 'tabIndex': PropTypes.string, + + /** + * Text to be displayed in a tooltip when hovering over the element. + */ + 'title': PropTypes.string, + + /** + * A callback for firing events to dash. + */ + 'fireEvent': PropTypes.func, + + 'dashEvents': PropTypes.oneOf(['click']) + +}; + +export default Noframes; diff --git a/src/components/Picture.react.js b/src/components/Picture.react.js new file mode 100644 index 00000000..f9410177 --- /dev/null +++ b/src/components/Picture.react.js @@ -0,0 +1,126 @@ + +import React, {PropTypes} from 'react'; + +const Picture = (props) => { + if (props.fireEvent || props.setProps) { + return ( + { + if (props.setProps) props.setProps({n_clicks: props.n_clicks + 1}); + if (props.fireEvent) props.fireEvent({event: 'click'}); + }} + {...props} + > + {props.children} + + ); + } else { + return ( + + {props.children} + + ); + } +}; + +Picture.defaultProps = { + n_clicks: 0 +}; + +Picture.propTypes = { + /** + * The ID of this component, used to identify dash components + * in callbacks. The ID needs to be unique across all of the + * components in an app. + */ + 'id': PropTypes.string, + + /** + * The children of this component + */ + 'children': PropTypes.node, + + /** + * An integer that represents the number of times + * that this element has been clicked on. + */ + 'n_clicks': PropTypes.integer, + + /** + * A unique identifier for the component, used to improve + * performance by React.js while rendering components + * See https://reactjs.org/docs/lists-and-keys.html for more info + */ + 'key': PropTypes.string, + + + /** + * Defines a keyboard shortcut to activate or add focus to the element. + */ + 'accessKey': PropTypes.string, + + /** + * Often used with CSS to style elements with common properties. + */ + 'className': PropTypes.string, + + /** + * Indicates whether the element's content is editable. + */ + 'contentEditable': PropTypes.string, + + /** + * Defines the ID of a element which will serve as the element's context menu. + */ + 'contextMenu': PropTypes.string, + + /** + * Defines the text direction. Allowed values are ltr (Left-To-Right) or rtl (Right-To-Left) + */ + 'dir': PropTypes.string, + + /** + * Defines whether the element can be dragged. + */ + 'draggable': PropTypes.string, + + /** + * Prevents rendering of given element, while keeping child elements, e.g. script elements, active. + */ + 'hidden': PropTypes.string, + + /** + * Defines the language used in the element. + */ + 'lang': PropTypes.string, + + /** + * Indicates whether spell checking is allowed for the element. + */ + 'spellCheck': PropTypes.string, + + /** + * Defines CSS styles which will override styles previously set. + */ + 'style': PropTypes.object, + + /** + * Overrides the browser's default tab order and follows the one specified instead. + */ + 'tabIndex': PropTypes.string, + + /** + * Text to be displayed in a tooltip when hovering over the element. + */ + 'title': PropTypes.string, + + /** + * A callback for firing events to dash. + */ + 'fireEvent': PropTypes.func, + + 'dashEvents': PropTypes.oneOf(['click']) + +}; + +export default Picture; diff --git a/src/index.js b/src/index.js index b4539df0..7fa01afc 100644 --- a/src/index.js +++ b/src/index.js @@ -8,10 +8,10 @@ import Article from './components/Article.react'; import Aside from './components/Aside.react'; import Audio from './components/Audio.react'; import B from './components/B.react'; -import Base from './components/Base.react'; import Basefont from './components/Basefont.react'; import Bdi from './components/Bdi.react'; import Bdo from './components/Bdo.react'; +import Bgsound from './components/Bgsound.react'; import Big from './components/Big.react'; import Blink from './components/Blink.react'; import Blockquote from './components/Blockquote.react'; @@ -59,6 +59,7 @@ import Hgroup from './components/Hgroup.react'; import Hr from './components/Hr.react'; import I from './components/I.react'; import Iframe from './components/Iframe.react'; +import Image from './components/Image.react'; import Img from './components/Img.react'; import Ins from './components/Ins.react'; import Isindex from './components/Isindex.react'; @@ -80,7 +81,9 @@ import Meter from './components/Meter.react'; import Multicol from './components/Multicol.react'; import Nav from './components/Nav.react'; import Nextid from './components/Nextid.react'; +import Nobr from './components/Nobr.react'; import Noembed from './components/Noembed.react'; +import Noframes from './components/Noframes.react'; import Noscript from './components/Noscript.react'; import ObjectEl from './components/ObjectEl.react'; import Ol from './components/Ol.react'; @@ -89,6 +92,7 @@ import Option from './components/Option.react'; import Output from './components/Output.react'; import P from './components/P.react'; import Param from './components/Param.react'; +import Picture from './components/Picture.react'; import Plaintext from './components/Plaintext.react'; import Pre from './components/Pre.react'; import Progress from './components/Progress.react'; @@ -133,4 +137,4 @@ import Video from './components/Video.react'; import Wbr from './components/Wbr.react'; import Xmp from './components/Xmp.react'; -export {A,Abbr,Acronym,Address,Applet,Area,Article,Aside,Audio,B,Base,Basefont,Bdi,Bdo,Big,Blink,Blockquote,Br,Button,Canvas,Caption,Center,Cite,Code,Col,Colgroup,Command,Content,Data,Datalist,Dd,Del,Details,Dfn,Dialog,Dir,Div,Dl,Dt,Element,Em,Embed,Fieldset,Figcaption,Figure,Font,Footer,Form,Frame,Frameset,H1,H2,H3,H4,H5,H6,Header,Hgroup,Hr,I,Iframe,Img,Ins,Isindex,Kbd,Keygen,Label,Legend,Li,Link,Listing,Main,MapEl,Mark,Marquee,Menu,Menuitem,Meta,Meter,Multicol,Nav,Nextid,Noembed,Noscript,ObjectEl,Ol,Optgroup,Option,Output,P,Param,Plaintext,Pre,Progress,Q,Rp,Rt,Rtc,Ruby,S,Samp,Script,Section,Select,Shadow,Slot,Small,Source,Spacer,Span,Strike,Strong,Sub,Summary,Sup,Table,Tbody,Td,Template,Textarea,Tfoot,Th,Thead,Time,Title,Tr,Track,Tt,U,Ul,Var,Video,Wbr,Xmp}; +export {A,Abbr,Acronym,Address,Applet,Area,Article,Aside,Audio,B,Basefont,Bdi,Bdo,Bgsound,Big,Blink,Blockquote,Br,Button,Canvas,Caption,Center,Cite,Code,Col,Colgroup,Command,Content,Data,Datalist,Dd,Del,Details,Dfn,Dialog,Dir,Div,Dl,Dt,Element,Em,Embed,Fieldset,Figcaption,Figure,Font,Footer,Form,Frame,Frameset,H1,H2,H3,H4,H5,H6,Header,Hgroup,Hr,I,Iframe,Image,Img,Ins,Isindex,Kbd,Keygen,Label,Legend,Li,Link,Listing,Main,MapEl,Mark,Marquee,Menu,Menuitem,Meta,Meter,Multicol,Nav,Nextid,Nobr,Noembed,Noframes,Noscript,ObjectEl,Ol,Optgroup,Option,Output,P,Param,Picture,Plaintext,Pre,Progress,Q,Rp,Rt,Rtc,Ruby,S,Samp,Script,Section,Select,Shadow,Slot,Small,Source,Spacer,Span,Strike,Strong,Sub,Summary,Sup,Table,Tbody,Td,Template,Textarea,Tfoot,Th,Thead,Time,Title,Tr,Track,Tt,U,Ul,Var,Video,Wbr,Xmp}; From 1fac733a2de0359a40196115b5b072242bfa6eca Mon Sep 17 00:00:00 2001 From: chriddyp Date: Fri, 23 Feb 2018 16:42:37 -0500 Subject: [PATCH 3/3] trigger ci build --- tests/test_integration.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_integration.py b/tests/test_integration.py index ef8abdd3..1f149d74 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -56,14 +56,14 @@ def snapshot(self, name): self.percy_runner.snapshot(name=name) def test_click(self): + call_count = Value('i', 0) + app = dash.Dash() app.layout = html.Div([ html.Div(id='container'), html.Button('Click', id='button', n_clicks=0) ]) - call_count = Value('i', 0) - @app.callback(Output('container', 'children'), [Input('button', 'n_clicks')]) def update_output(n_clicks): call_count.value += 1