9
9
import dash_core_components as dcc
10
10
import dash_flow_example
11
11
12
+ from selenium .webdriver .common .action_chains import ActionChains
13
+ from selenium .webdriver .common .keys import Keys
14
+
12
15
import dash
13
16
14
17
from dash .dependencies import Input , Output
@@ -59,7 +62,15 @@ def update_output(value):
59
62
self .percy_snapshot (name = 'simple-callback-1' )
60
63
61
64
input1 = self .wait_for_element_by_id ('input' )
62
- input1 .clear ()
65
+
66
+ chain = (ActionChains (self .driver )
67
+ .click (input1 )
68
+ .send_keys (Keys .HOME )
69
+ .key_down (Keys .SHIFT )
70
+ .send_keys (Keys .END )
71
+ .key_up (Keys .SHIFT )
72
+ .send_keys (Keys .DELETE ))
73
+ chain .perform ()
63
74
64
75
input1 .send_keys ('hello world' )
65
76
@@ -69,7 +80,8 @@ def update_output(value):
69
80
self .assertEqual (
70
81
call_count .value ,
71
82
# an initial call to retrieve the first value
72
- 1 +
83
+ # and one for clearing the input
84
+ 2 +
73
85
# one for each hello world character
74
86
len ('hello world' )
75
87
)
@@ -111,7 +123,14 @@ def update_text(data):
111
123
self .percy_snapshot (name = 'wildcard-callback-1' )
112
124
113
125
input1 = self .wait_for_element_by_id ('input' )
114
- input1 .clear ()
126
+ chain = (ActionChains (self .driver )
127
+ .click (input1 )
128
+ .send_keys (Keys .HOME )
129
+ .key_down (Keys .SHIFT )
130
+ .send_keys (Keys .END )
131
+ .key_up (Keys .SHIFT )
132
+ .send_keys (Keys .DELETE ))
133
+ chain .perform ()
115
134
116
135
input1 .send_keys ('hello world' )
117
136
@@ -121,7 +140,8 @@ def update_text(data):
121
140
self .assertEqual (
122
141
input_call_count .value ,
123
142
# an initial call
124
- 1 +
143
+ # and a call for clearing the input
144
+ 2 +
125
145
# one for each hello world character
126
146
len ('hello world' )
127
147
)
@@ -326,6 +346,7 @@ def test_index_customization(self):
326
346
<footer>
327
347
{%config%}
328
348
{%scripts%}
349
+ {%renderer%}
329
350
</footer>
330
351
<div id="custom-footer">My custom footer</div>
331
352
<script>
@@ -378,6 +399,7 @@ def test_assets(self):
378
399
<footer>
379
400
{%config%}
380
401
{%scripts%}
402
+ {%renderer%}
381
403
</footer>
382
404
</body>
383
405
</html>
@@ -493,6 +515,7 @@ def test_external_files_init(self):
493
515
<footer>
494
516
{%config%}
495
517
{%scripts%}
518
+ {%renderer%}
496
519
</footer>
497
520
</body>
498
521
</html>
@@ -532,6 +555,171 @@ def create_layout():
532
555
self .startServer (app )
533
556
time .sleep (0.5 )
534
557
558
+ def test_with_custom_renderer (self ):
559
+ app = dash .Dash (__name__ )
560
+
561
+ app .index_string = '''
562
+ <!DOCTYPE html>
563
+ <html>
564
+ <head>
565
+ {%metas%}
566
+ <title>{%title%}</title>
567
+ {%favicon%}
568
+ {%css%}
569
+ </head>
570
+ <body>
571
+ <div>Testing custom DashRenderer</div>
572
+ {%app_entry%}
573
+ <footer>
574
+ {%config%}
575
+ {%scripts%}
576
+ <script id="_dash-renderer" type="application/javascript">
577
+ console.log('firing up a custom renderer!')
578
+ const renderer = new DashRenderer({
579
+ request_pre: () => {
580
+ var output = document.getElementById('output-pre')
581
+ if(output) {
582
+ output.innerHTML = 'request_pre changed this text!';
583
+ }
584
+ },
585
+ request_post: () => {
586
+ var output = document.getElementById('output-post')
587
+ if(output) {
588
+ output.innerHTML = 'request_post changed this text!';
589
+ }
590
+ }
591
+ })
592
+ </script>
593
+ </footer>
594
+ <div>With request hooks</div>
595
+ </body>
596
+ </html>
597
+ '''
598
+
599
+ app .layout = html .Div ([
600
+ dcc .Input (
601
+ id = 'input' ,
602
+ value = 'initial value'
603
+ ),
604
+ html .Div (
605
+ html .Div ([
606
+ html .Div (id = 'output-1' ),
607
+ html .Div (id = 'output-pre' ),
608
+ html .Div (id = 'output-post' )
609
+ ])
610
+ )
611
+ ])
612
+
613
+ @app .callback (Output ('output-1' , 'children' ), [Input ('input' , 'value' )])
614
+ def update_output (value ):
615
+ return value
616
+
617
+ self .startServer (app )
618
+
619
+ input1 = self .wait_for_element_by_id ('input' )
620
+ chain = (ActionChains (self .driver )
621
+ .click (input1 )
622
+ .send_keys (Keys .HOME )
623
+ .key_down (Keys .SHIFT )
624
+ .send_keys (Keys .END )
625
+ .key_up (Keys .SHIFT )
626
+ .send_keys (Keys .DELETE ))
627
+ chain .perform ()
628
+
629
+ input1 .send_keys ('fire request hooks' )
630
+
631
+ self .wait_for_text_to_equal ('#output-1' , 'fire request hooks' )
632
+ self .wait_for_text_to_equal ('#output-pre' , 'request_pre changed this text!' )
633
+ self .wait_for_text_to_equal ('#output-post' , 'request_post changed this text!' )
634
+
635
+ self .percy_snapshot (name = 'request-hooks' )
636
+
637
+ def test_with_custom_renderer_interpolated (self ):
638
+
639
+ renderer = '''
640
+ <script id="_dash-renderer" type="application/javascript">
641
+ console.log('firing up a custom renderer!')
642
+ const renderer = new DashRenderer({
643
+ request_pre: () => {
644
+ var output = document.getElementById('output-pre')
645
+ if(output) {
646
+ output.innerHTML = 'request_pre changed this text!';
647
+ }
648
+ },
649
+ request_post: () => {
650
+ var output = document.getElementById('output-post')
651
+ if(output) {
652
+ output.innerHTML = 'request_post changed this text!';
653
+ }
654
+ }
655
+ })
656
+ </script>
657
+ '''
658
+ class CustomDash (dash .Dash ):
659
+
660
+ def interpolate_index (self , ** kwargs ):
661
+ return '''
662
+ <!DOCTYPE html>
663
+ <html>
664
+ <head>
665
+ <title>My App</title>
666
+ </head>
667
+ <body>
668
+
669
+ <div id="custom-header">My custom header</div>
670
+ {app_entry}
671
+ {config}
672
+ {scripts}
673
+ {renderer}
674
+ <div id="custom-footer">My custom footer</div>
675
+ </body>
676
+ </html>
677
+ ''' .format (
678
+ app_entry = kwargs ['app_entry' ],
679
+ config = kwargs ['config' ],
680
+ scripts = kwargs ['scripts' ],
681
+ renderer = renderer )
682
+
683
+ app = CustomDash ()
684
+
685
+ app .layout = html .Div ([
686
+ dcc .Input (
687
+ id = 'input' ,
688
+ value = 'initial value'
689
+ ),
690
+ html .Div (
691
+ html .Div ([
692
+ html .Div (id = 'output-1' ),
693
+ html .Div (id = 'output-pre' ),
694
+ html .Div (id = 'output-post' )
695
+ ])
696
+ )
697
+ ])
698
+
699
+ @app .callback (Output ('output-1' , 'children' ), [Input ('input' , 'value' )])
700
+ def update_output (value ):
701
+ return value
702
+
703
+ self .startServer (app )
704
+
705
+ input1 = self .wait_for_element_by_id ('input' )
706
+ chain = (ActionChains (self .driver )
707
+ .click (input1 )
708
+ .send_keys (Keys .HOME )
709
+ .key_down (Keys .SHIFT )
710
+ .send_keys (Keys .END )
711
+ .key_up (Keys .SHIFT )
712
+ .send_keys (Keys .DELETE ))
713
+ chain .perform ()
714
+
715
+ input1 .send_keys ('fire request hooks' )
716
+
717
+ self .wait_for_text_to_equal ('#output-1' , 'fire request hooks' )
718
+ self .wait_for_text_to_equal ('#output-pre' , 'request_pre changed this text!' )
719
+ self .wait_for_text_to_equal ('#output-post' , 'request_post changed this text!' )
720
+
721
+ self .percy_snapshot (name = 'request-hooks interpolated' )
722
+
535
723
def test_late_component_register (self ):
536
724
app = dash .Dash ()
537
725
0 commit comments