tauri_test.cc 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. // +build ignore
  2. #include <cassert>
  3. #include <cstdio>
  4. #include <functional>
  5. #include <iostream>
  6. #include <string>
  7. #include <thread>
  8. #include <utility>
  9. #include <vector>
  10. #define WEBVIEW_IMPLEMENTATION
  11. #include "tauri.h"
  12. extern "C" void webview_dispatch_proxy(struct webview *w, void *arg) {
  13. (*static_cast<std::function<void(struct webview *)> *>(arg))(w);
  14. }
  15. class runner {
  16. public:
  17. runner(struct webview *w) : w(w) { webview_init(this->w); }
  18. ~runner() { webview_exit(this->w); }
  19. runner &then(std::function<void(struct webview *w)> fn) {
  20. auto arg = new std::pair<std::function<void(struct webview *)>, void *>(
  21. fn, nullptr);
  22. this->queue.push_back([=](struct webview *w) {
  23. webview_dispatch(
  24. w,
  25. [](struct webview *w, void *arg) {
  26. auto dispatch_arg = reinterpret_cast<
  27. std::pair<std::function<void(struct webview *)>, void *> *>(
  28. arg);
  29. dispatch_arg->first(w);
  30. delete dispatch_arg;
  31. },
  32. reinterpret_cast<void *>(arg));
  33. });
  34. return *this;
  35. }
  36. runner &sleep(const int millis) {
  37. this->queue.push_back([=](struct webview *w) {
  38. (void)w;
  39. std::this_thread::sleep_for(std::chrono::milliseconds(millis));
  40. });
  41. return *this;
  42. }
  43. void wait() {
  44. this->then([](struct webview *w) { webview_terminate(w); });
  45. auto q = this->queue;
  46. auto w = this->w;
  47. std::thread bg_thread([w, q]() {
  48. for (auto f : q) {
  49. f(w);
  50. }
  51. });
  52. while (webview_loop(w, 1) == 0) {
  53. }
  54. bg_thread.join();
  55. }
  56. private:
  57. struct webview *w;
  58. std::vector<std::function<void(struct webview *)>> queue;
  59. };
  60. static void test_minimal() {
  61. struct webview w = {};
  62. std::cout << "TEST: minimal" << std::endl;
  63. w.title = "Minimal test";
  64. w.width = 480;
  65. w.height = 320;
  66. webview_init(&w);
  67. webview_dispatch(&w,
  68. [](struct webview *w, void *arg) {
  69. (void)arg;
  70. webview_terminate(w);
  71. },
  72. nullptr);
  73. while (webview_loop(&w, 1) == 0) {
  74. }
  75. webview_exit(&w);
  76. }
  77. static void test_window_size() {
  78. struct webview w = {};
  79. std::vector<std::string> results;
  80. std::cout << "TEST: window size" << std::endl;
  81. w.width = 480;
  82. w.height = 320;
  83. w.resizable = 1;
  84. w.userdata = static_cast<void *>(&results);
  85. w.external_invoke_cb = [](struct webview *w, const char *arg) {
  86. auto *v = static_cast<std::vector<std::string> *>(w->userdata);
  87. v->push_back(std::string(arg));
  88. };
  89. runner(&w)
  90. .then([](struct webview *w) {
  91. webview_eval(w, "window.external.invoke(''+window.screen.width+' ' + "
  92. "window.screen.height)");
  93. webview_eval(w, "window.external.invoke(''+window.innerWidth+' ' + "
  94. "window.innerHeight)");
  95. })
  96. .sleep(200)
  97. .then([](struct webview *w) { webview_set_fullscreen(w, 1); })
  98. .sleep(500)
  99. .then([](struct webview *w) {
  100. webview_eval(w, "window.external.invoke(''+window.innerWidth+' ' + "
  101. "window.innerHeight)");
  102. })
  103. .sleep(200)
  104. .then([](struct webview *w) { webview_set_fullscreen(w, 0); })
  105. .sleep(500)
  106. .then([](struct webview *w) {
  107. webview_eval(w, "window.external.invoke(''+window.innerWidth+' ' + "
  108. "window.innerHeight)");
  109. })
  110. .wait();
  111. assert(results.size() == 4);
  112. assert(results[1] == "480 320");
  113. assert(results[0] == results[2]);
  114. assert(results[1] == results[3]);
  115. }
  116. static void test_inject_js() {
  117. struct webview w = {};
  118. std::vector<std::string> results;
  119. std::cout << "TEST: inject JS" << std::endl;
  120. w.width = 480;
  121. w.height = 320;
  122. w.userdata = static_cast<void *>(&results);
  123. w.external_invoke_cb = [](struct webview *w, const char *arg) {
  124. auto *v = static_cast<std::vector<std::string> *>(w->userdata);
  125. v->push_back(std::string(arg));
  126. };
  127. runner(&w)
  128. .then([](struct webview *w) {
  129. webview_eval(w,
  130. R"(document.body.innerHTML = '<div id="foo">Foo</div>';)");
  131. webview_eval(
  132. w,
  133. "window.external.invoke(document.getElementById('foo').innerText)");
  134. })
  135. .wait();
  136. assert(results.size() == 1);
  137. assert(results[0] == "Foo");
  138. }
  139. static void test_inject_css() {
  140. struct webview w = {};
  141. std::vector<std::string> results;
  142. std::cout << "TEST: inject CSS" << std::endl;
  143. w.width = 480;
  144. w.height = 320;
  145. w.userdata = static_cast<void *>(&results);
  146. w.external_invoke_cb = [](struct webview *w, const char *arg) {
  147. auto *v = static_cast<std::vector<std::string> *>(w->userdata);
  148. v->push_back(std::string(arg));
  149. };
  150. runner(&w)
  151. .then([](struct webview *w) {
  152. webview_inject_css(w, "#app { margin-left: 4px; }");
  153. webview_eval(w, "window.external.invoke(getComputedStyle(document."
  154. "getElementById('app')).marginLeft)");
  155. })
  156. .wait();
  157. assert(results.size() == 1);
  158. assert(results[0] == "4px");
  159. }
  160. int main() {
  161. test_minimal();
  162. test_window_size();
  163. test_inject_js();
  164. test_inject_css();
  165. return 0;
  166. }