Skip to content

Commit 91c71e8

Browse files
committed
chore: add renderer-test example graphic, intended to be used to test functionality of a Renderer.
1 parent 3ca94a7 commit 91c71e8

File tree

3 files changed

+257
-0
lines changed

3 files changed

+257
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Renderer Test Graphic
2+
3+
This Graphic presents a number of steps for the renderer to perform.
4+
5+
It intended to be used to test the functionality of a renderer.
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
class Graphic extends HTMLElement {
2+
connectedCallback() {
3+
// Called when the element is added to the DOM
4+
// Note: Don't paint any pixels at this point, wait for load() to be called
5+
}
6+
7+
async load(params) {
8+
this.style.fontSize = "24px";
9+
10+
// Note: the OGraf specification says that the load() method should not paint any pixels.
11+
// This directive is ignored in this test graphic.
12+
13+
const infoMessageContainer = document.createElement("div");
14+
infoMessageContainer.style.color = "#000";
15+
infoMessageContainer.style.position = "absolute";
16+
infoMessageContainer.style.top = "25%";
17+
infoMessageContainer.style.left = "0%";
18+
infoMessageContainer.style.right = "0%";
19+
infoMessageContainer.style.textAlign = "center";
20+
infoMessageContainer.style.zIndex = 1;
21+
this.appendChild(infoMessageContainer);
22+
23+
24+
const infoMessage = document.createElement("div");
25+
infoMessage.style.backgroundColor = "#ffffff";
26+
infoMessage.style.display = "inline-block";
27+
infoMessage.style.padding = "1em";
28+
infoMessageContainer.appendChild(infoMessage);
29+
this.infoMessage = infoMessage
30+
31+
this._infoMessage('Starting up...')
32+
33+
if (params.renderCharacteristics &&
34+
params.renderCharacteristics.resolution
35+
) {
36+
// This fills the background with a red box, which should be covered by the blue fill below
37+
const fullContainer = document.createElement("div");
38+
fullContainer.style.position = "absolute";
39+
fullContainer.style.top = '0'
40+
fullContainer.style.left = '0'
41+
fullContainer.style.right = '0'
42+
fullContainer.style.bottom = '0'
43+
fullContainer.style.backgroundColor = "#f00";
44+
this.appendChild(fullContainer);
45+
46+
// This paints a blue box, which should be the size of the renderer
47+
const sizedContainer = document.createElement("div");
48+
sizedContainer.style.position = "absolute";
49+
sizedContainer.style.top = '0'
50+
sizedContainer.style.left = '0'
51+
sizedContainer.style.width = `${params.renderCharacteristics.resolution.width}px`
52+
sizedContainer.style.height = `${params.renderCharacteristics.resolution.height}px`
53+
sizedContainer.style.backgroundColor = "#87a0de";
54+
this.appendChild(sizedContainer);
55+
56+
}
57+
58+
return this._handleAction('load', params);
59+
}
60+
async dispose(_params) {
61+
this.innerHTML = "";
62+
}
63+
async updateAction(params) {
64+
return this._handleAction('updateAction', params);
65+
}
66+
async playAction(params) {
67+
return this._handleAction('playAction', params);
68+
}
69+
async stopAction(params) {
70+
return this._handleAction('stopAction', params);
71+
}
72+
async customAction(params) {
73+
return this._handleAction('customAction', params);
74+
}
75+
76+
loggedActions = []
77+
_handleAction(type, params) {
78+
const lastAction = { type, params }
79+
this.loggedActions.push(lastAction);
80+
81+
const currentStep = this.steps[this.stepIndex]
82+
if (!currentStep) {
83+
return this._infoMessage('No more steps to verify, this test is completed');
84+
}
85+
let error = currentStep.verify(lastAction)
86+
87+
88+
if (!error) {
89+
this.stepIndex++
90+
91+
const nextStep = this.steps[this.stepIndex]
92+
93+
if (nextStep) {
94+
return this._infoMessage(`${currentStep.completed ? `${currentStep.completed}\n` : ''}Step ${this.stepIndex} completed.\nNext, ${nextStep.prompt}`);
95+
} else {
96+
return this._infoMessage('No more steps to verify, this test is completed');
97+
}
98+
} else {
99+
100+
this._errorMessage(`Expected ${currentStep.prompt}\n${error}`)
101+
102+
}
103+
}
104+
105+
106+
_errorMessage(error) {
107+
this.infoMessage.innerHTML = this._formatText(error)
108+
this.infoMessage.style.backgroundColor = "#bb0000";
109+
this.infoMessage.style.color = "#fff";
110+
111+
return {
112+
statusCode: 400,
113+
statusMessage: error
114+
}
115+
}
116+
_infoMessage(str) {
117+
this.infoMessage.innerHTML = this._formatText(str)
118+
this.infoMessage.style.backgroundColor = "#fff";
119+
this.infoMessage.style.color = "#000";
120+
121+
return {
122+
statusCode: 200,
123+
statusMessage: str
124+
}
125+
}
126+
_formatText(str) {
127+
return str.replaceAll(/\n/g, "<br>");
128+
}
129+
130+
131+
steps = [
132+
{
133+
prompt: 'N/A',
134+
completed: 'load() method seems okay!',
135+
verify: (lastAction) => {
136+
if (lastAction.type !== 'load') return 'Expected the load() method to be called'
137+
if (lastAction.params.renderType !== 'realtime') return 'Only realtime rendering is supported by this graphic!'
138+
if (!lastAction.params.data) return 'No `data` argument provided to the load() method'
139+
if (!lastAction.params.data.message) return 'Expected a `message` argument in the `data` object provided to the load() method'
140+
}
141+
},
142+
{
143+
prompt: 'call the playAction() method (with no skipAnimation set)',
144+
verify: (lastAction) => {
145+
if (lastAction.type !== 'playAction') return 'Expected the playAction() method to be called';
146+
if (lastAction.params.skipAnimation) return 'Expected "skipAnimation" to be undefined or false, got true';
147+
}
148+
},
149+
{
150+
prompt: 'call the playAction() method, with skipAnimation set to true.',
151+
verify: (lastAction) => {
152+
if (lastAction.type !== 'playAction') return 'Expected the playAction() method to be called';
153+
if (lastAction.params.skipAnimation !== true) return `Expected the playAction to be called with { skipAnimation: true }, got ${JSON.stringify(lastAction.params)}`;
154+
}
155+
},
156+
{
157+
prompt: `call the playAction() method, with 'goto' set to 4.`,
158+
verify: (lastAction) => {
159+
if (lastAction.type !== 'playAction') return 'Expected the playAction() method to be called';
160+
if (lastAction.params.goto !== 4) return `Expected the playAction to be called with 'goto' set to 4, got ${JSON.stringify(lastAction.params)}`;
161+
if (lastAction.params.delta !== undefined) return `Expected the playAction to be called with 'delta' being undefined, got ${JSON.stringify(lastAction.params)}`;
162+
}
163+
},
164+
{
165+
prompt: `call the playAction() method, with 'delta' set to -1.`,
166+
verify: (lastAction) => {
167+
if (lastAction.type !== 'playAction') return 'Expected the playAction() method to be called';
168+
if (lastAction.params.delta !== -1) return `Expected the playAction to be called with 'delta' set to -1, got ${JSON.stringify(lastAction.params)}`;
169+
if (lastAction.params.goto !== undefined) return `Expected the playAction to be called with 'goto' being undefined, got ${JSON.stringify(lastAction.params)}`;
170+
}
171+
},
172+
{
173+
prompt: `call the updateAction() method, with data { message: 'Hello' }`,
174+
verify: (lastAction) => {
175+
if (lastAction.type !== 'updateAction') return 'Expected the updateAction() method to be called';
176+
if (lastAction.params.data.message !== 'Hello') return `Expected the updateAction to be called with 'delta' set to -1, got ${JSON.stringify(lastAction.params)}`;
177+
}
178+
},
179+
{
180+
prompt: `call the stopAction() method`,
181+
verify: (lastAction) => {
182+
if (lastAction.type !== 'stopAction') return 'Expected the stopAction() method to be called';
183+
}
184+
},
185+
{
186+
prompt: 'call the stopAction() method, with skipAnimation set to true.',
187+
verify: (lastAction) => {
188+
if (lastAction.type !== 'stopAction') return 'Expected the stopAction() method to be called';
189+
if (lastAction.params.skipAnimation !== true) return `Expected the stopAction to be called with { skipAnimation: true }, got ${JSON.stringify(lastAction.params)}`;
190+
}
191+
},
192+
{
193+
prompt: 'call the customAction() method for the "highlight" action',
194+
verify: (lastAction) => {
195+
if (lastAction.type !== 'customAction') return 'Expected the customAction() method to be called';
196+
if (lastAction.params.id !== 'highlight') return `Expected the customAction() method to be called with id "highlight", got ${JSON.stringify(lastAction.params)}`;
197+
}
198+
},
199+
{
200+
prompt: 'call the customAction() method for the "setColor" action, with payload { color: "red" }',
201+
verify: (lastAction) => {
202+
if (lastAction.type !== 'customAction') return 'Expected the customAction() method to be called';
203+
if (lastAction.params.id !== 'setColor') return `Expected the customAction() method to be called with id "setColor", got ${JSON.stringify(lastAction.params)}`;
204+
if (typeof lastAction.params.payload !== 'object') return `Property "payload" is missing in argument, got ${JSON.stringify(lastAction.params)}`;
205+
if (lastAction.params.payload.color !== 'red') return `Expected property "payload.color" to have the value "red", got ${JSON.stringify(lastAction.params)}`;
206+
}
207+
},
208+
]
209+
210+
stepIndex = 0
211+
}
212+
213+
export default Graphic;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"$schema": "https://ograf.ebu.io/v1-draft-0/specification/json-schemas/graphics/schema.json",
3+
"name": "Renderer Test Graphic",
4+
"description": "This Graphic is used to validate a Renderer",
5+
"id": "renderer-test",
6+
"supportsRealTime": true,
7+
"supportsNonRealTime": false,
8+
"schema": {
9+
"type": "object",
10+
"properties": {
11+
"message": {
12+
"type": "string",
13+
"title": "Message",
14+
"default": "Hello"
15+
}
16+
}
17+
},
18+
"customActions": [
19+
{
20+
"id": "highlight",
21+
"name": "Highlight",
22+
"schema": null
23+
},
24+
{
25+
"id": "setColor",
26+
"name": "Set Color",
27+
"schema": {
28+
"type": "object",
29+
"properties": {
30+
"color": {
31+
"type": "string",
32+
"title": "Color",
33+
"default": "red"
34+
}
35+
}
36+
}
37+
}
38+
]
39+
}

0 commit comments

Comments
 (0)