forked from tensorflow/tensorboard
-
Notifications
You must be signed in to change notification settings - Fork 0
/
core_test.py
219 lines (187 loc) · 8.59 KB
/
core_test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Basic TensorBoard functional tests using WebDriver."""
import collections
import os
import subprocess
import unittest
import tempfile
from selenium.webdriver.common import by
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support import wait
from testing.web import webtest
from tensorboard.plugins.scalar import scalars_demo
from tensorboard.plugins.audio import audio_demo
_BASE_PORT = 8000
_PORT_OFFSETS = collections.defaultdict(lambda: len(_PORT_OFFSETS))
class BasicTest(unittest.TestCase):
"""Tests that the basic chrome is displayed when there is no data."""
@classmethod
def setUpClass(cls):
src_dir = os.environ["TEST_SRCDIR"]
binary = os.path.join(
src_dir, "org_tensorflow_tensorboard/tensorboard/tensorboard"
)
cls.logdir = tempfile.mkdtemp(
prefix="core_test_%s_logdir_" % cls.__name__
)
cls.setUpData()
cls.port = _BASE_PORT + _PORT_OFFSETS[cls]
cls.process = subprocess.Popen(
[binary, "--port", str(cls.port), "--logdir", cls.logdir]
)
@classmethod
def setUpData(cls):
# Overridden by DashboardsTest.
pass
@classmethod
def tearDownClass(cls):
cls.process.kill()
cls.process.wait()
def setUp(self):
self.driver = webtest.new_webdriver_session()
self.driver.get("http://localhost:%s" % self.port)
self.wait = wait.WebDriverWait(self.driver, 10)
def tearDown(self):
try:
self.driver.quit()
finally:
self.driver = None
self.wait = None
def testToolbarTitleDisplays(self):
self.wait.until(
expected_conditions.text_to_be_present_in_element(
(by.By.CLASS_NAME, "toolbar-title"), "TensorBoard"
)
)
def testLogdirDisplays(self):
self.wait.until(
expected_conditions.text_to_be_present_in_element(
(by.By.ID, "data_location"), self.logdir
)
)
class DashboardsTest(BasicTest):
"""Tests basic behavior when there is some data in TensorBoard.
This extends `BasicTest`, so it inherits its methods to test that
the basic chrome is displayed. We also check that we can navigate
around the various dashboards.
"""
@classmethod
def setUpData(cls):
scalars_demo.run_all(cls.logdir, verbose=False)
audio_demo.run_all(cls.logdir, verbose=False)
def testLogdirDisplays(self):
# TensorBoard doesn't have logdir display when there is data
pass
def testDashboardSelection(self):
"""Test that we can navigate among the different dashboards."""
selectors = {
"scalars_tab": "paper-tab[data-dashboard=scalars]",
"audio_tab": "paper-tab[data-dashboard=audio]",
"graphs_tab": "paper-tab[data-dashboard=graphs]",
"inactive_dropdown": "paper-dropdown-menu[label*=Inactive]",
"images_menu_item": "paper-item[data-dashboard=images]",
"reload_button": "paper-icon-button#reload-button",
}
elements = {}
for (name, selector) in selectors.items():
locator = (by.By.CSS_SELECTOR, selector)
self.wait.until(
expected_conditions.presence_of_element_located(locator)
)
elements[name] = self.driver.find_element_by_css_selector(selector)
# The implementation of paper-* components doesn't seem to play nice
# with Selenium's `element.is_selected()` and `element.is_enabled()`
# methods. Instead, we check the appropriate WAI-ARIA attributes.
# (Also, though the docs for `get_attribute` say that the string
# `"false"` is returned as `False`, this appears to be the case
# _sometimes_ but not _always_, so we should take special care to
# handle that.)
def is_selected(element):
attribute = element.get_attribute("aria-selected")
return attribute and attribute != "false"
def is_enabled(element):
attribute = element.get_attribute("aria-disabled")
is_disabled = attribute and attribute != "false"
return not is_disabled
def assert_selected_dashboard(polymer_component_name):
expected = {polymer_component_name}
actual = {
container.find_element_by_css_selector(
"*"
).tag_name # first child
for container in self.driver.find_elements_by_css_selector(
".dashboard-container"
)
if container.is_displayed()
}
self.assertEqual(expected, actual)
# The scalar and audio dashboards should be active, and the scalar
# dashboard should be selected by default. The images menu item
# should not be visible, as it's within the drop-down menu.
self.assertTrue(elements["scalars_tab"].is_displayed())
self.assertTrue(elements["audio_tab"].is_displayed())
self.assertTrue(elements["graphs_tab"].is_displayed())
self.assertTrue(is_selected(elements["scalars_tab"]))
self.assertFalse(is_selected(elements["audio_tab"]))
self.assertFalse(elements["images_menu_item"].is_displayed())
self.assertFalse(is_selected(elements["images_menu_item"]))
assert_selected_dashboard("tf-scalar-dashboard")
# While we're on the scalar dashboard, we should be allowed to
# reload the data.
self.assertTrue(is_enabled(elements["reload_button"]))
# We should be able to activate the audio dashboard.
elements["audio_tab"].click()
self.assertFalse(is_selected(elements["scalars_tab"]))
self.assertTrue(is_selected(elements["audio_tab"]))
self.assertFalse(is_selected(elements["graphs_tab"]))
self.assertFalse(is_selected(elements["images_menu_item"]))
assert_selected_dashboard("tf-audio-dashboard")
self.assertTrue(is_enabled(elements["reload_button"]))
# We should then be able to open the dropdown and navigate to the
# image dashboard. (We have to wait until it's visible because of the
# dropdown menu's animations.)
elements["inactive_dropdown"].click()
self.wait.until(
expected_conditions.visibility_of(elements["images_menu_item"])
)
self.assertTrue(elements["images_menu_item"].is_displayed())
elements["images_menu_item"].click()
self.assertFalse(is_selected(elements["scalars_tab"]))
self.assertFalse(is_selected(elements["audio_tab"]))
self.assertFalse(is_selected(elements["graphs_tab"]))
self.assertTrue(is_selected(elements["images_menu_item"]))
assert_selected_dashboard("tf-image-dashboard")
self.assertTrue(is_enabled(elements["reload_button"]))
# Next, we should be able to navigate back to an active dashboard.
# If we choose the graphs dashboard, the reload feature should be
# disabled.
elements["graphs_tab"].click()
self.assertFalse(elements["images_menu_item"].is_displayed())
self.assertFalse(is_selected(elements["scalars_tab"]))
self.assertFalse(is_selected(elements["audio_tab"]))
self.assertTrue(is_selected(elements["graphs_tab"]))
self.assertFalse(is_selected(elements["images_menu_item"]))
assert_selected_dashboard("tf-graph-dashboard")
self.assertFalse(is_enabled(elements["reload_button"]))
# Finally, we should be able to navigate back to the scalar dashboard.
elements["scalars_tab"].click()
self.assertTrue(is_selected(elements["scalars_tab"]))
self.assertFalse(is_selected(elements["audio_tab"]))
self.assertFalse(is_selected(elements["graphs_tab"]))
self.assertFalse(is_selected(elements["images_menu_item"]))
assert_selected_dashboard("tf-scalar-dashboard")
self.assertTrue(is_enabled(elements["reload_button"]))
if __name__ == "__main__":
unittest.main()