123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- from typing import List
- import numpy as np
- from selenium.common.exceptions import JavascriptException
- from nicegui import ui
- from nicegui.elements.scene_object3d import Object3D
- from nicegui.testing import Screen
- def test_moving_sphere_with_timer(screen: Screen):
- with ui.scene() as scene:
- sphere = scene.sphere().with_name('sphere')
- ui.timer(0.1, lambda: sphere.move(0, 0, sphere.z + 0.01))
- screen.open('/')
- def position() -> float:
- for _ in range(3):
- try:
- pos = screen.selenium.execute_script(
- f'return scene_{scene.html_id}.getObjectByName("sphere").position.z')
- if pos is not None:
- return pos
- except JavascriptException as e:
- print(e.msg, flush=True)
- screen.wait(1.0)
- raise RuntimeError('Could not get position')
- screen.wait(0.2)
- assert position() > 0
- def test_no_object_duplication_on_index_client(screen: Screen):
- with ui.scene() as scene:
- sphere = scene.sphere().move(0, -4, 0)
- ui.timer(0.1, lambda: sphere.move(0, sphere.y + 0.5, 0))
- screen.open('/')
- screen.wait(0.4)
- screen.switch_to(1)
- screen.open('/')
- screen.switch_to(0)
- screen.wait(0.2)
- assert screen.selenium.execute_script(f'return scene_{scene.html_id}.children.length') == 5
- def test_no_object_duplication_with_page_builder(screen: Screen):
- scene_html_ids: List[int] = []
- @ui.page('/')
- def page():
- with ui.scene() as scene:
- sphere = scene.sphere().move(0, -4, 0)
- ui.timer(0.1, lambda: sphere.move(0, sphere.y + 0.5, 0))
- scene_html_ids.append(scene.html_id)
- screen.open('/')
- screen.wait(0.4)
- screen.switch_to(1)
- screen.open('/')
- screen.switch_to(0)
- screen.wait(0.2)
- assert screen.selenium.execute_script(f'return scene_{scene_html_ids[0]}.children.length') == 5
- screen.switch_to(1)
- screen.wait(0.2)
- assert screen.selenium.execute_script(f'return scene_{scene_html_ids[1]}.children.length') == 5
- def test_deleting_group(screen: Screen):
- with ui.scene() as scene:
- with scene.group() as group:
- scene.sphere()
- ui.button('Delete group', on_click=group.delete)
- screen.open('/')
- screen.wait(0.5)
- assert len(scene.objects) == 2
- screen.click('Delete group')
- screen.wait(0.5)
- assert len(scene.objects) == 0
- def test_replace_scene(screen: Screen):
- with ui.row() as container:
- with ui.scene() as scene:
- scene.sphere().with_name('sphere')
- def replace():
- container.clear()
- with container:
- nonlocal scene
- with ui.scene() as scene:
- scene.box().with_name('box')
- ui.button('Replace scene', on_click=replace)
- screen.open('/')
- screen.wait(0.5)
- assert screen.selenium.execute_script(f'return scene_{scene.html_id}.children[4].name') == 'sphere'
- screen.click('Replace scene')
- screen.wait(0.5)
- assert screen.selenium.execute_script(f'return scene_{scene.html_id}.children[4].name') == 'box'
- def test_create_dynamically(screen: Screen):
- ui.button('Create', on_click=ui.scene)
- screen.open('/')
- screen.click('Create')
- assert screen.find_by_tag('canvas')
- def test_rotation_matrix_from_euler():
- omega, phi, kappa = 0.1, 0.2, 0.3
- Rx = np.array([[1, 0, 0], [0, np.cos(omega), -np.sin(omega)], [0, np.sin(omega), np.cos(omega)]])
- Ry = np.array([[np.cos(phi), 0, np.sin(phi)], [0, 1, 0], [-np.sin(phi), 0, np.cos(phi)]])
- Rz = np.array([[np.cos(kappa), -np.sin(kappa), 0], [np.sin(kappa), np.cos(kappa), 0], [0, 0, 1]])
- R = Rz @ Ry @ Rx
- assert np.allclose(Object3D.rotation_matrix_from_euler(omega, phi, kappa), R)
- def test_object_creation_via_context(screen: Screen):
- with ui.scene() as scene:
- scene.box().with_name('box')
- screen.open('/')
- screen.wait(0.5)
- assert screen.selenium.execute_script(f'return scene_{scene.html_id}.children[4].name') == 'box'
- def test_object_creation_via_attribute(screen: Screen):
- scene = ui.scene()
- scene.box().with_name('box')
- screen.open('/')
- screen.wait(0.5)
- assert screen.selenium.execute_script(f'return scene_{scene.html_id}.children[4].name') == 'box'
- def test_clearing_scene(screen: Screen):
- with ui.scene() as scene:
- scene.box().with_name('box')
- with scene.group(): # see https://github.com/zauberzeug/nicegui/issues/4560
- scene.box().with_name('box2')
- ui.button('Clear', on_click=scene.clear)
- screen.open('/')
- screen.wait(0.5)
- assert len(scene.objects) == 3
- screen.click('Clear')
- screen.wait(0.5)
- assert len(scene.objects) == 0
- def test_gltf(screen: Screen):
- with ui.scene() as scene:
- scene.gltf('https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Box/glTF-Binary/Box.glb')
- screen.open('/')
- screen.wait(1.0)
- assert screen.selenium.execute_script(f'return scene_{scene.html_id}.children.length') == 5
|