git.iko.soy/typeable/elm-ui
on master help sign in
add text metrics to the metrics harvester
4ea86abElm UI Automation
tests-rendering/src/Testable/Runner.elm+56−54
@@ -46,7 +46,7 @@ program tests =
46 cur :: remaining ->
46 cur :: remaining ->
47 ( Just cur, remaining )
47 ( Just cur, remaining )
48 in
48 in
49− Browser.document
49+ Browser.element
50 { init =
50 { init =
51 always
51 always
52 ( { current = current
52 ( { current = current
@@ -136,8 +136,9 @@ type Msg
136 (List
136 (List
137 { id : String
137 { id : String
138 , bbox : Testable.BoundingBox
138 , bbox : Testable.BoundingBox
139− , isVisible : Bool
140 , style : List ( String, String )
139 , style : List ( String, String )
140+ , isVisible : Bool
141+ , textMetrics : List TextMetrics
141 }
142 }
142 )
143 )
143
144
@@ -225,70 +226,61 @@ update msg model =
225 )
226 )
226
227
227
228
228−view : Model Msg -> Browser.Document Msg
229+view : Model Msg -> Html.Html Msg
229view model =
230view model =
230 case model.current of
231 case model.current of
231 Nothing ->
232 Nothing ->
232 if List.isEmpty model.upcoming then
233 if List.isEmpty model.upcoming then
233− { title = "tests finished"
234− , body =
235− [ case model.finished of
234+ case model.finished of
236− [] ->
235+ [] ->
237− Element.layout [] <|
236+ Element.layout [] <|
237+ Element.column
238+ [ Element.spacing 20
239+ , Element.padding 20
240+ , Element.width (Element.px 800)
241+ ]
242+ [ Element.none ]
243+
244+ finished :: remaining ->
245+ Element.layout
246+ [ Font.size 16
247+ , Element.inFront (Element.html (viewElementHighlight model))
248+ ]
249+ <|
250+ Element.row [ Element.width Element.fill ]
251+ [ Element.el
252+ [ Element.width Element.fill
253+ ]
254+ (Element.el
255+ [ Element.centerX
256+ , Element.padding 100
257+ , Border.dashed
258+ , Border.width 2
259+ , Border.color palette.lightGrey
260+ , Font.size 20
261+ , Element.inFront
262+ (Element.el
263+ [ Font.size 14
264+ , Font.color palette.lightGrey
265+ ]
266+ (Element.text "test case")
267+ )
268+ ]
269+ (Testable.toElement finished.element)
270+ )
238− Element.column
271+ , Element.column
239 [ Element.spacing 20
272 [ Element.spacing 20
240 , Element.padding 20
273 , Element.padding 20
241− , Element.width (Element.px 800)
274+ , Element.width Element.fill
242 ]
275 ]
243− [ Element.none ]
244−
245− finished :: remaining ->
276+ (List.map viewResult (finished :: remaining))
246− Element.layout
247− [ Font.size 16
248− , Element.inFront (Element.html (viewElementHighlight model))
249 ]
277 ]
250− <|
251− Element.row [ Element.width Element.fill ]
252− [ Element.el
253− [ Element.width Element.fill
254− ]
255− (Element.el
256− [ Element.centerX
257− , Element.padding 100
258− , Border.dashed
259− , Border.width 2
260− , Border.color palette.lightGrey
261− , Font.size 20
262− , Element.inFront
263− (Element.el
264− [ Font.size 14
265− , Font.color palette.lightGrey
266− ]
267− (Element.text "test case")
268− )
269− ]
270− (Testable.toElement finished.element)
271− )
272− , Element.column
273− [ Element.spacing 20
274− , Element.padding 20
275− , Element.width Element.fill
276− ]
277− (List.map viewResult (finished :: remaining))
278− ]
279− ]
280− }
281
278
282 else
279 else
283− { title = "tests finished"
280+ Html.text ""
284− , body = []
285− }
286
281
287 Just ( label, current ) ->
282 Just ( label, current ) ->
288− { title = "running"
289− , body =
290− [ Testable.toHtml current ]
283+ Testable.toHtml current
291− }
292
284
293
285
294viewElementHighlight model =
286viewElementHighlight model =
@@ -492,7 +484,17 @@ port styles :
492 , bbox : Testable.BoundingBox
484 , bbox : Testable.BoundingBox
493 , style : List ( String, String )
485 , style : List ( String, String )
494 , isVisible : Bool
486 , isVisible : Bool
487+ , textMetrics : List TextMetrics
495 }
488 }
496 -> msg
489 -> msg
497 )
490 )
498 -> Sub msg
491 -> Sub msg
492+
493+
494+type alias TextMetrics =
495+ { actualBoundingBoxAscent : Float
496+ , actualBoundingBoxDescent : Float
497+ , actualBoundingBoxLeft : Float
498+ , actualBoundingBoxRight : Float
499+ , width : Float
500+ }
tests-rendering/view/view.html+73−3
@@ -6,10 +6,45 @@
6 <script type="text/javascript" src="./elm.js"></script>
6 <script type="text/javascript" src="./elm.js"></script>
7 </head>
7 </head>
8 <style></style>
8 <style></style>
9− <body id="root"></body>
9+ <body id="root">
10+ <div id="elm-home"></div>
11+ <canvas id="canvas"></canvas>
12+ </body>
10
13
11 <script type="text/javascript">
14 <script type="text/javascript">
15+ // Calculations for canvas
16+ var PIXEL_RATIO = (function () {
17+ var ctx = document.createElement("canvas").getContext("2d"),
18+ dpr = window.devicePixelRatio || 1,
19+ bsr =
20+ ctx.webkitBackingStorePixelRatio ||
21+ ctx.mozBackingStorePixelRatio ||
22+ ctx.msBackingStorePixelRatio ||
23+ ctx.oBackingStorePixelRatio ||
24+ ctx.backingStorePixelRatio ||
25+ 1;
26+
27+ return dpr / bsr;
28+ })();
29+
30+ function createHiDPICanvas(w, h, id, ratio) {
31+ if (!ratio) {
32+ ratio = PIXEL_RATIO;
33+ }
34+ let can = document.getElementById(id);
35+ can.width = w * ratio;
36+ can.height = h * ratio;
37+ can.style.width = w + "px";
38+ can.style.height = h + "px";
39+ can.getContext("2d").setTransform(ratio, 0, 0, ratio, 0, 0);
40+ return can;
41+ }
42+ // create a canvas for text measurements
43+ let canvas = createHiDPICanvas(200, 100, "canvas");
44+ // Starting Elm App,
12− var app = Elm.WeirdCentering.init();
45+ var app = Elm.WeirdCentering.init({
46+ node: document.getElementById("elm-home"),
47+ });
13
48
14 var test_results = "waiting..";
49 var test_results = "waiting..";
15
50
@@ -29,10 +64,17 @@
29 }
64 }
30 var style = getStyle(element);
65 var style = getStyle(element);
31 var bbox = getBoundingBox(element);
66 var bbox = getBoundingBox(element);
67+ var metrics = getTextMetrics(element);
32
68
33 var visible = isVisible(id, bbox);
69 var visible = isVisible(id, bbox);
34
70
71+ var result = {
72+ textMetrics: metrics,
73+ bbox: bbox,
74+ style: style,
75+ id: id,
35− var result = { bbox: bbox, style: style, id: id, isVisible: visible };
76+ isVisible: visible,
77+ };
36 results.push(result);
78 results.push(result);
37 }
79 }
38 app.ports.styles.send(results);
80 app.ports.styles.send(results);
@@ -100,5 +142,33 @@
100 padding: padding,
142 padding: padding,
101 };
143 };
102 }
144 }
145+ function getTextMetrics(element) {
146+ // Given our element, we want to return the text metrics on the text within.
147+ // If it is an element we want to measure:
148+ // we want to get the font family
149+ // and the font size.
150+ // We're going to presume that the font is loaded.
151+ let childrenTextMetrics = [];
152+ for (i = 0; i < element.children.length; i++) {
153+ if (element.children[i].classList.contains("t")) {
154+ let style = window.getComputedStyle(element, null);
155+ let fontSize = style.getPropertyValue("font-size");
156+ let fontFamily = style.getPropertyValue("font-family");
157+ let ctx = canvas.getContext("2d");
158+
159+ ctx.font = fontSize + " " + fontFamily; //"16px Roboto";
160+ let text = ctx.measureText(element.children[i].innerText);
161+
162+ childrenTextMetrics.push({
163+ actualBoundingBoxAscent: text.actualBoundingBoxAscent,
164+ actualBoundingBoxDescent: text.actualBoundingBoxDescent,
165+ actualBoundingBoxLeft: text.actualBoundingBoxLeft,
166+ actualBoundingBoxRight: text.actualBoundingBoxRight,
167+ width: text.width,
168+ });
169+ }
170+ }
171+ return childrenTextMetrics;
172+ }
103 </script>
173 </script>
104</html>
174</html>