10
10
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11
11
# License for the specific language governing permissions and limitations
12
12
# under the License.
13
-
13
+ from pathlib import Path
14
14
from typing import Optional
15
15
16
16
import urllib3
17
+ from typing_extensions import Self
17
18
18
19
from selenium import webdriver
19
20
from selenium .webdriver .common .options import ArgOptions
20
21
from testcontainers .core .container import DockerContainer
22
+ from testcontainers .core .network import Network
21
23
from testcontainers .core .waiting_utils import wait_container_is_ready
24
+ from testcontainers .selenium .video import SeleniumVideoContainer
22
25
23
- IMAGES = {"firefox" : "selenium/standalone-firefox-debug :latest" , "chrome" : "selenium/standalone-chrome-debug :latest" }
26
+ IMAGES = {"firefox" : "selenium/standalone-firefox:latest" , "chrome" : "selenium/standalone-chrome:latest" }
24
27
25
28
26
29
def get_image_name (capabilities : str ) -> str :
@@ -51,6 +54,8 @@ def __init__(
51
54
self .image = image or get_image_name (capabilities )
52
55
self .port = port
53
56
self .vnc_port = vnc_port
57
+ self .video = None
58
+ self .__video_network = None
54
59
super ().__init__ (image = self .image , ** kwargs )
55
60
self .with_exposed_ports (self .port , self .vnc_port )
56
61
@@ -72,3 +77,44 @@ def get_connection_url(self) -> str:
72
77
ip = self .get_container_host_ip ()
73
78
port = self .get_exposed_port (self .port )
74
79
return f"http://{ ip } :{ port } /wd/hub"
80
+
81
+ def with_video (self , image : Optional [str ] = None , video_path : Optional [Path ] = None ) -> Self :
82
+ video_path = video_path or Path .cwd ()
83
+
84
+ self .video = SeleniumVideoContainer (image )
85
+
86
+ video_folder_path = video_path .parent if video_path .suffix else video_path
87
+ self .video .set_videos_host_path (str (video_folder_path .resolve ()))
88
+
89
+ if video_path .name :
90
+ self .video .set_video_name (video_path .name )
91
+
92
+ return self
93
+
94
+ def start (self ) -> "DockerContainer" :
95
+ if not self .video :
96
+ super ().start ()
97
+ return self
98
+
99
+ self .__video_network = Network ().__enter__ ()
100
+
101
+ self .with_kwargs (network = self .__video_network .name )
102
+ super ().start ()
103
+
104
+ self .video .with_kwargs (network = self .__video_network .name ).set_selenium_container_host (
105
+ self .get_wrapped_container ().short_id
106
+ ).start ()
107
+
108
+ return self
109
+
110
+ def stop (self , force = True , delete_volume = True ) -> None :
111
+ if self .video :
112
+ # get_wrapped_container().stop -> stop the container
113
+ # video.stop -> remove the container
114
+ self .video .get_wrapped_container ().stop ()
115
+ self .video .stop (force , delete_volume )
116
+
117
+ super ().stop (force , delete_volume )
118
+
119
+ if self .__video_network :
120
+ self .__video_network .remove ()
0 commit comments